I am implementing a interface for various companies to use the same Flask Admin instance to add and assign roles to their various users. However, I wish to make it so only the users which belong to the company viewing the data appear in the dropdowns that represent the one-to-many relationship between roles and users.
Is there something like get_query
, but for the dropdown values?
Here is my current code for my view
class RoleView(ModelView):
def get_query(self):
return super(RoleView, self).get_query().filter(
Role.company_id == current_user.company.id
)
def get_count_query(self):
return super(RoleView, self).get_count_query().filter(
Role.company_id == current_user.company.id
)
and the model
class Role(db.Model):
id = db.Column(db.Integer(), primary_key=True)
name = db.Column(db.String(80), unique=True)
description = db.Column(db.String(255))
users = db.relationship(
'User',
backref="role",
lazy="dynamic"
)
company_id = db.Column(
db.Integer,
db.ForeignKey('company.id'),
nullable=False
)
Thanks
After digging through the source, I found this interesting line that led me to the correct answer https://github.com/flask-admin/flask-admin/blob/0f9f4b8695e3a7d00d9f3bae5fbf8f47f6a24e55/flask_admin/contrib/sqla/form.py#L81
The QuerySelectMultipleField
form field has a field called query_factory
which accepts a function. So we can override this with form_args
and a lambda
:
class RoleView(ModelView):
column_exclude_list = ['company']
form_excluded_columns = ['company']
form_args = {
'users': {
'query_factory': lambda: User.query.filter_by(
company_id=current_user.company_id
)
}
}
def get_query(self):
return super(RoleView, self).get_query().filter(
Role.company_id == current_user.company.id
)
def get_count_query(self):
return super(RoleView, self).get_count_query().filter(
Role.company_id == current_user.company.id
)