使用Flask-Admin更新MongoDB ReferenceField

时间:2015-02-28 15:17:04

标签: python mongodb flask-admin

我正在尝试创建一个管理页面,我可以使用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视图和cilck save中选择用户角色时,会显示以下表单验证错误:'54a72849426c702850d01922'不是此字段的有效选择

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

1 个答案:

答案 0 :(得分:0)

你的模特看起来很好。但是你的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会为您执行此操作。您只需在创建用户对象之前先创建角色。

此外,您可以使用烧瓶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')

这有助于您正确更新参考文献。