Flask Admin doesn't show all fields - flask-admin

I have model like this:
class User(db.Model):
__tablename__ = 'users'
__table_args__ = {'mysql_engine' : 'InnoDB', 'mysql_charset' : 'utf8'}
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
email = db.Column(db.String(120), unique=True)
_password = db.Column('password', db.String(80))
def __init__(self, username = None, email = None, password = None):
self.username = username
self.email = email
self._set_password(password)
def _set_password(self, password):
self._password = generate_password_hash(password)
def _get_password(self):
return self._password
def check_password(self, password):
return check_password_hash(self._password, password)
password = db.synonym("_password", descriptor=property(_get_password, _set_password))
def __repr__(self):
return '<User %r>' % self.username
I have ModelView:
class UserAdmin(sqlamodel.ModelView):
searchable_columns = ('username', 'email')
excluded_list_columns = ['password']
list_columns = ('username', 'email')
form_columns = ('username', 'email', 'password')
But no matter what i do, flask admin didn't show password field when i'm editing user info. Is there any way ? Even just to edit hash code.
UPDATE: https://github.com/mrjoes/flask-admin/issues/78

Reason why it did not work - Flask-Admin was not able to figure out what to do with SynonymProperty, so it failed to generate form field.
There's a way you can have it working right now:
class UserAdmin(sqlamodel.ModelView):
searchable_columns = ('username', 'email')
excluded_list_columns = ['password']
list_columns = ('username', 'email')
form_columns = ('username', 'email')
def scaffold_form(self):
form_class = super(UserAdmin, self).scaffold_form()
form_class.password = wtf.TextField('Password')
return form_class
I pushed simple fix which adds support for the SynonymProperty, so it will work even without form customization. Unfortunately, I'm in process of adding MongoDB backend, so I won't be able to release new version any time soon.
Just in case, SynonymProperty was superseded by hybrid properties in SQLAlchemy 0.7 and onward, which should be supported by the Flask-Admin.

Much better:
from wtforms.fields import PasswordField
class UserAdmin(sqlamodel.ModelView):
searchable_columns = ('username', 'email')
excluded_list_columns = ['password']
form_overrides = dict(password=PasswordField)

Related

on form submit user session data is lost

I am working on a codeigniter listing application, everything is working fine in the application but when I am submitting the listing form, the user session data is lost.
I am having: agentId in session, which is visible after login but after submitting it is not in the session data.
Code:
$agentId = $this->session->userdata('agentId');
var_dump($this->session->userdata);
die;
\\ This session showing all user data including agentId
$data['p_title'] = $this->project_model->projectName().' :: Property : Add New Property';
$data['Message'] = '';
$data['heading'] = 'Property: Add New Property';
$data['pageName'] = 'property';
$data['title'] = filter_value('title', '');
$data['meta_decription'] = filter_value('meta_decription', '');
$data['keywords'] = filter_value('keywords', '');
$data['type'] = filter_value('type', '');
$data['sub_type'] = filter_value('sub_type', '');
//$data['sub_type1'] = filter_value('sub_type1', '');
$data['bedrooms'] = filter_value('bedrooms', '');
$data['kitchen'] = filter_value('kitchen', '');
$data['parking'] = filter_value('parking', 'YES');
$data['bathrooms'] = filter_value('bathrooms', '');
$data['area'] = filter_value('area', '');
$data['price'] = filter_value('price', '0.00');
$data['location'] = filter_value('location', '');
$data['city'] = filter_value('city', 82);
$data['country'] = filter_value('country', 102);
$data['details'] = filter_value('details', '');
$data['featured'] = filter_value('featured', 'NO');
$data['countries'] = $this->general_model->listCountries($data['country']);
$data['cities'] = $this->general_model->listCities($data['country'], $data['city']);
$this->form_validation->set_rules('title', 'Property title', 'trim|required');
if($this->form_validation->run() === TRUE){
$agentId = $this->session->userdata('agentId');
var_dump($this->session->userdata);
die;
\\ but here the agent id and rest of user session data is removed.
$Date = getCurrentDate();
$Time = getCurrentTime();
$DbFieldsAry = array('agentId', 'title', 'meta_decription', 'keywords', 'type', 'sub_type', 'bedrooms', 'kitchen', 'parking', 'bathrooms', 'area', 'price', 'location', 'city', 'country', 'details', 'featured', 'date');
$InfoAry = array($this->session->userdata('agentId'), $data['title'], $data['meta_decription'], $data['keywords'], $data['type'], $data['sub_type'], $data['bedrooms'], $data['kitchen'], $data['parking'], $data['bathrooms'], $data['area'], $data['price'], $data['location'], $data['city'], $data['country'], $data['details'], $data['featured'], $Date);
if($this->general_model->addInfo_Simple($DbFieldsAry, $InfoAry, 'tbl_properties_list')){
$activityId = $this->general_model->getSingleValue($data['title'], 'title', 'property_id', 'tbl_properties_list');
setMessage('success_message', 'New property added successfully. Add pictures to property.');
redirect(base_url().'property/update/'.$activityId.'/0', 'refresh');
}
else{
setMessage('error_message', 'Unable to perofrm this operation, please try again later!');
redirect(base_url().'property/user_listing', 'refresh');
}
}
$data['allowed'] = true;
$data['warning'] = '';
if(!isSuperAdmin()){
$total_properties = $this->general_model->getTotalDataSimple1('property_id','tbl_properties_list');
if(allowed_properties() <= $total_properties){
$data['allowed'] = false;
$data['warning'] = '<br/>You have reached to maximum limit of your property upload listing.<br/>Click HERE to change payment plan.<br/><br/><br/><br/><br/>';
}
}
$this->load->view('add_property', $data);
The first var_dump for session check shows all session data, but why is all the user session data lost after submitting?

Select statement in cases with sqlalchemy

We are implementing a workflow engine with SQLAlchemy.
Two tables in our model are:
class DbAttribute(Base):
__tablename__ = "db_dbattribute"
id = Column(Integer, primary_key = True)
dbnode_id = Column(Integer, ForeignKey('db_dbnode.id'))
key = Column(String(255))
datatype = Column(String(10))
tval = Column(String, default='')
fval = Column(Float, default=None, nullable=True)
ival = Column(Integer, default=None, nullable=True)
bval = Column(Boolean, default=None, nullable=True)
dval = Column(DateTime, default=None, nullable=True)
class DbNode(Base):
__tablename__ = "db_dbnode"
id = Column(Integer, primary_key=True)
uuid = Column(UUID(as_uuid=True), default=uuid_func)
type = Column(String(255), index=True)
label = Column(String(255), index=True, nullable=True)
description = Column(Text(), nullable=True)
ctime = Column(DateTime(timezone=True), default=timezone.now)
mtime = Column(DateTime(timezone=True), default=timezone.now)
Attributes are related to a Node via the dbnode_id foreign key.
I am now working on a query that would return an attribute value (for example tval) and None if this row does not exists because the key is not the right one. This is working on aliased classes now:
select_stmt =select([aliased_attributes.tval]).select_from(
aliased_attributes
).where(and_(
aliased_attributes.key==attrkey,
aliased_attributes.dbnode_id==aliased_node.id
))
exists_stmt = exists(select_stmt)
entity = case([
(
exists_stmt,
select_stmt
),
(
text('true'),
None
)
])
This exits now with the following error:
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) syntax error at or near "SELECT"
I am using SQLAlchemy 1.0.12 and postgresql 9.4.
Any help on what I missed or other ways this could be done better are greatly appreciated
Cheers
Why not just use simple outerjoin?
attrkey = 'my_attr_key'
q = (
session
.query(
DbNode.label,
DbAttribute.tval,
)
.outerjoin(
DbAttribute,
and_(
DbAttribute.dbnode_id == DbNode.id,
DbAttribute.key == attrkey,
)
)
)

How to set custmer id for an quote in magento?

I am adding product into cart and tried to map customer id,email to that quote
using the below code
$product_id = 123;
$qty = 1;
$product = Mage::getModel('catalog/product')->load($product_id);
$cart = Mage::getModel('checkout/cart');
$cart->init();
$superAttributeArray = array('151' => '3');
$params = array(
'product' => $product_id,
'qty' => $qty,
'super_attribute' => $superAttributeArray
);
$cart->addProduct($product, $params);
$cart->save();
$currenQuoteId = Mage::getSingleton('checkout/session')->getQuoteId();
$store = Mage::getSingleton('core/store')->load(Mage::app()->getStore()->getId());
$quote = Mage::getModel('sales/quote')->setStore($store)->load($currenQuoteId);
$quote->setCustomerId('1')->setCustomerEmail('test#gmail.com')->setCustomerFirstname('firstname')->setCustomerLastname('lastname');
$quote->save();
When I try to set customerid,email,fname,lname am getting error as "Mage registry key "controller" already exists".
Can anyone help me in fixing this issue?
Something like this might work
$customerObj = Mage::getModel('customer/customer')->load($customerId);
$quoteObj = Mage::getModel('sales/quote')->assignCustomer($customerObj);
$storeId = Mage::app()->getStore()->getId();
$quoteObj->setStore(Mage::getSingleton('core/store')->load($storeId);
$productObj = Mage::getModel('catalog/product')->load($productId);
$quoteItem = Mage::getModel('sales/quote_item')->setProduct($productObj);
$quoteItem->setQuote($quoteObj);
$quoteItem->setQty('1');
$quoteItem->setStoreId($storeId);
$quoteObj->addItem($quoteItem);
$quoteObj->setStoreId($storeId);
$quoteObj->collectTotals();
$quoteObj->save();

Filter users by user group in tastypie

This is my user resource class
class UserResource(ModelResource):
class Meta:
queryset = User.objects.all()
allowed_methods = ['get', 'post', 'put', 'patch']
resource_name = 'user'
excludes = ['password']
#authentication = SessionAuthentication()
#authorization = DjangoAuthorization()
authorization = Authorization()
authentication = Authentication()
always_return_data = True
filtering = {
'id': ALL,
'username': ALL,
'groups': ALL_WITH_RELATIONS
}
I want to filter user by their group names.
Like /api/v1/user/?format=json&groups__name=group_name
The above format is not working. How can i filter it in the get request?
You have to add relational fields from model that you are going to use to your resource. In first place you have to create Model resource for Group model. Then create To Many field in UserResource linked to GroupResource.
Something like this:
class GroupResource(ModelResource):
class Meta:
queryset = Group.objects.all()
resource_name = 'group'
authorization = Authorization()
authentication = Authentication()
always_return_data = True
filtering = {
'id': ALL,
'name': ALL,
}
class UserResource(ModelResource):
groups = fields.ToManyField(GroupResource, 'groups',
blank=True)
class Meta:
queryset = User.objects.all()
allowed_methods = ['get', 'post', 'put', 'patch']
resource_name = 'user'
excludes = ['password']
#authentication = SessionAuthentication()
#authorization = DjangoAuthorization()
authorization = Authorization()
authentication = Authentication()
always_return_data = True
filtering = {
'id': ALL,
'username': ALL,
'groups': ALL_WITH_RELATIONS
}
The reason of that is Tastypie has to know relational object authorization, authentication, resource_name and rest bunch of settings that can't populate itself.

cakephp2 how to send email using gmail smtp dynamically to a closed mailing list

Is there anyway in php or cakephp, to send email using smtp so that I can send email to a closed/internal mailing list. e.g:
In my company we have an email list: appsteam#company.com, which can only be send if a person also using xxx#company.com email. outside from that email it will be blocked. so in cakephp is there anyway to somehow take the user credential and send email under a company or maybe in gmail email, if it's google group
I think what I actually want will be, how to set up cakephp email so that it send just like I send directly from the email server, if I use gmail, then I want it looks like gmail (header, etc)
what the final code will do is supposedly, I will take credential from users for their email, and send the mail using that. here is my code for AbcComponent.php
/*
* Abc components
*/
class AbcComponent extends Component {
public $options = array();
/**
* Constructor
**/
public function __construct(ComponentCollection $collection, $options = array()){
parent::__construct($collection,$options);
$this->options = array_merge($this->options, $options);
}
public function send_link ($user_email = null, $recipients = null, $subject = null, $message = null, $group_id = null, $user_id = null, $email_id = null, $download_password = null) {
$final_subject = $subject;
$final_recipients = $recipients;
$final_message = $message;
App::uses('CakeEmail', 'Network/Email');
$recipients = str_replace(' ', '', $recipients);
$recipients = explode(',', $recipients);
$recipient_queue_num = 1;
//Send the email one by one
foreach ($recipients as $recipient) :
$email = new CakeEmail();
$email->delivery = 'smtp';
//$email->from($user_email);
$email->from('xxxxx#gmail.com');
$email->to($recipient);
$email->smtpOptions = array(
'port'=>'465',
'timeout'=>'30',
'host' => 'ssl://smtp.gmail.com',
'username'=>'xxxxx#gmail.com', //this will be later grab from dbase based on user
'password'=>'password',
);
$email->subject($final_subject);
$email->template('download_link_email');
$email->emailFormat('both');
$email->viewVars(array('final_message' => $final_message));
if($email->send()) {
debug('email is sent');
} else {
debug('email is not sent');
}
//queue number increase for hashing purpose
$recipient_queue_num++;
endforeach;
}
$this->Email->delivery = ...
and later
$email = new CakeEmail();
Where is your "new object" statement before trying to access it?
You cannot just use it without.
You are also using both $this->Email and $email. This is probably your mistake (copy and paste errors).
$this->Email = new CakeEmail();
$this->Email->delivery = ...
...
"Indirect modification of overloaded property" is usually always an indicator of a non declared object that you are trying to access.