2015-02-28 2 views
1

Я пытаюсь создать страницу администрирования, из которой я могу редактировать, какие роли пользователь участвует в использовании MonogDB и Flask-Admin.Обновление MongoDB ReferenceField с использованием 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)) 

Когда я выбираю роли пользователя в представлении edit_form Колба-администратора и cilck сохранения, после проверки формы ошибка: '54a72849426c702850d01922' не допустимый выбор для этого поля

Каков правильный способ редактирования/обновления ReferenceField?

ответ

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 бы сделать это для вас. Перед созданием User Object вам просто нужно создать роли.

Кроме того, вы можете создать начальную пользователя с помощью колба'S 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('[email protected]'): 
     user_datastore.create_user(email='[email protected]', password=encrypted_password) 
     user_datastore.add_role_to_user('[email protected]', 'admin') 

Это поможет вам в обновлении ссылки правильно.