Flask-Admin编辑表单使用QuerySelectMultipleField报错如何解决
Flask-Admin 自定义User模型角色多选表单解决方案
错误原因
你遇到的两个报错分别由两个配置错误导致:
TypeError: 'method' object is not iterable:query_factory参数你写的是lambda: Role.query.all,返回的是all方法本身,没有执行查询,需要加括号调用得到角色列表。AttributeError: 'QuerySelectMultipleField' object has no attribute '_value':Select2TagsWidget是用于自由输入文本标签的控件,不需要绑定数据库查询结果,和QuerySelectMultipleField不兼容,不需要额外指定这个控件。
另外你自定义的role_sel额外字段没有和模型的roles属性做双向同步,就算渲染成功也无法保存/回显角色数据。
最优解决方案
不需要自定义额外字段,Flask-Admin原生支持渲染多对多关系为多选控件,直接配置如下即可:
from flask_admin.contrib.sqla import ModelView from flask_admin.contrib.sqla.fields import QuerySelectMultipleField from wtforms import PasswordField from app import db from app.models import Role, User class UserView(ModelView): column_display_pk = True form_extra_fields = { 'password': PasswordField('Password'), } # 指定roles字段用多选查询字段渲染 form_overrides = { 'roles': QuerySelectMultipleField } # 配置roles字段的查询参数 form_args = { 'roles': { 'query_factory': lambda: Role.query.all(), 'allow_blank': False } } form_columns = ( 'username', 'password', 'firstname', 'lastname', 'roles', ) def on_model_change(self, form, User, is_created): if form.password.data != '': User.set_password(form.password.data)
如果你坚持使用自定义role_sel字段
需要补充字段和模型属性的双向同步逻辑:
from flask_admin.contrib.sqla import ModelView from flask_admin.contrib.sqla.fields import QuerySelectMultipleField from flask_admin.form import Select2Widget from wtforms import PasswordField from app import db from app.models import Role, User class UserView(ModelView): column_display_pk = True form_extra_fields = { 'password': PasswordField('Password'), 'role_sel': QuerySelectMultipleField( label='Roles', query_factory=lambda: Role.query.all(), widget=Select2Widget(multiple=True) ) } form_columns = ( 'username', 'password', 'firstname', 'lastname', 'role_sel', ) # 编辑页面回显角色数据 def on_form_prefill(self, form, id): user = User.query.get(id) form.role_sel.data = user.roles def on_model_change(self, form, User, is_created): if form.password.data != '': User.set_password(form.password.data) # 同步选择的角色到模型属性 User.roles = form.role_sel.data
内容的提问来源于stack exchange,提问作者Darwin von Corax
相关产品推荐
相关产品推荐

