【问题标题】:Update MongoDB ReferenceField using Flask-Admin使用 Flask-Admin 更新 MongoDB ReferenceField
【发布时间】:2015-02-28 15:17:04
【问题描述】:

我正在尝试创建一个管理页面,在该页面中我可以使用 MonogDB 和 Flask-Admin 编辑用户属于哪些角色。

models.py

class Role(db.Document, RoleMixin):
    name = db.StringField(max_length=80, unique=True)
    description = db.StringField(max_length=255)

    def __unicode__(self):
        return self.name

class User(db.Document, UserMixin):
    email = db.StringField(max_length=255)
    password = db.StringField(max_length=255)
    roles = db.ListField(db.ReferenceField(Role))

admin.py

class UserView(ModelView):
    from wtforms.fields import SelectMultipleField
    from bson import ObjectId, DBRef
    form_overrides = dict(roles=SelectMultipleField)
    options = [(g.id, g.name) for g in models.Role.objects()]
    # print options
    # [(ObjectId('54a72849426c702850d01921'), u'community'),
    #  (ObjectId('54a72849426c702850d01922'), u'customer')]
    form_args = dict(roles=dict(choices=options))

当我在 Flask-Admin edit_form 视图中选择用户角色并单击保存时,显示以下表单验证错误:'54a72849426c702850d01922' is not a valid selection for this field

编辑/更新 ReferenceField 的正确方法是什么?

【问题讨论】:

    标签: python mongodb flask-admin


    【解决方案1】:

    您的模型看起来不错。但是您的ModelView 是问题所在。我正在使用 MongoEngine,这是我的实现。

    class Role(db.Document, RoleMixin):
        name = db.StringField(max_length=80, unique=True)
        description = db.StringField(max_length=255)
    
        def __unicode__(self):
            return self.name
    
    
    class User(db.Document, UserMixin):
        email = db.StringField(max_length=255)
        password = db.StringField(max_length=500)
        active = db.BooleanField(default=True)
        confirmed_at = db.DateTimeField()
        roles = db.ListField(db.ReferenceField(Role), default=[])
    
        # Optional to override save method.
        def save(self, *args, **kwargs):
            self.password = encrypt_password(self.password) # You can encrypt your password before storing in db, as a good practice.
            self.confirmed_at = datetime.now()
    
            super(User, self).save(*args, **kwargs)
    

    这是我的模型视图:

    class UserView(ModelView):
        can_create = True
        can_delete = True
        can_edit = True
        decorators = [login_required]
    
        column_filters = ('email',)
    
        def is_accessible(self):
            return current_user.has_role("admin")
    
    class RoleView(ModelView):
        can_create = True
        can_delete = True
        can_edit = True
        decorators = [login_required]
    
        def is_accessible(self):
            return current_user.has_role("admin")
    

    您不必显式获取所有角色对象,flask-admin 会为您完成。您只需在创建用户对象之前先创建角色。

    另外,你可以像这样使用flask的before_first_request创建一个初始用户:

    @app.before_first_request
    def before_first_request():
        user_datastore.find_or_create_role(name='admin', description='Administrator')
        encrypted_password = encrypt_password('password') # Put in your password here
        if not user_datastore.get_user('user@example.com'):
            user_datastore.create_user(email='user@example.com', password=encrypted_password)
            user_datastore.add_role_to_user('user@example.com', 'admin')
    

    这将帮助您正确更新参考。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-16
      • 1970-01-01
      • 1970-01-01
      • 2019-05-22
      • 2014-04-27
      • 1970-01-01
      相关资源
      最近更新 更多