2015-10-07 8 views
1

У меня есть простая заявка, полный код представлен here. Он использует склянки-админFlask-admin: catch changes on inline_models

модели:

class User(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    username = db.Column(db.String, unique=True) 


class UserNote(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    body = db.Column(db.String, nullable=False) 
    user_id = db.Column(db.Integer, db.ForeignKey('users.id')) 
    author_id = db.Column(db.Integer, db.ForeignKey('users.id')) 
    user = db.relationship(User, 
          foreign_keys='UserNote.user_id', 
          backref=db.backref('user_notes', order_by=id)) 
    author = db.relationship(User, 
          foreign_keys='UserNote.author_id', 
          backref=db.backref('author_user_notes', 
               order_by=id)) 

и главный app.py:

app = Flask(__name__) 

class ModelFormWithAuthorship(InlineFormAdmin): 
    def on_model_change(self, form, model): 
     user = User.query.first() 
     print('++++++') 
     print(user) 
     print(model) 
     print('++++++') 
     model.author = user 

class UserModelView(ModelView): 
    inline_models = (ModelFormWithAuthorship(UserNote),) 


admin = Admin(app, url='/admin', name='MyAdmin', template_mode='bootstrap3') 
admin.add_view(UserModelView(User, db.session)) 

Я хочу, чтобы автоматически установить первый пользователь из запроса в качестве автора измененного UserNote , Это упрощение для текущего зарегистрированного пользователя.

Но флажок admin передает все встроенные модели этому методу.

Вот шаги для reporduce

  1. Запуск приложения
  2. Создать пользователя с именем user1 (этот пользователь может быть первым())
  3. Создать пользователя с именем admin1
  4. Создать пользователя с именем admin2
  5. Создайте 2 встроенные заметки, у него будет user1 как автор
  6. Связаться с базой данных напрямую и сменить автора o е один из записки к Admin1 и другое примечание к admin2
  7. Перейти к Колба-администратора и убедитесь, что у вас есть 2 примечания от 2 пользователей
  8. Редактировать тело первой ноты и нажмите сохранить

Ожидаемый результат для этих действий для меня был, это первое примечание будет иметь user1, поскольку автор и автор второй заметки останутся прежними. Но Фактический результат:: автор для обеих нот, установленных пользователем1.

Я пытался отладить, и нашел некоторые интересные атрибуты:

# Not changed note 
model._sa_instance_state._attached = {bool} True 
model._sa_instance_state.deleted = {bool} False 
model._sa_instance_state.detached = {bool} False 
model._sa_instance_state.expired = {bool} False 
model._sa_instance_state.has_identity = {bool} True 
model._sa_instance_state.pending = {bool} False 
model._sa_instance_state.persistent = {bool} True 
model._sa_instance_state.transient = {bool} False 
model.body = {str} 'test1' 
model._sa_instance_state.modified = {bool} True 

# Changed note 
model._sa_instance_state._attached = {bool} True 
model._sa_instance_state.deleted = {bool} False 
model._sa_instance_state.detached = {bool} False 
model._sa_instance_state.expired = {bool} False 
model._sa_instance_state.has_identity = {bool} True 
model._sa_instance_state.pending = {bool} False 
model._sa_instance_state.persistent = {bool} True 
model._sa_instance_state.transient = {bool} False 
model.body = {str} 'test2A' 
model._sa_instance_state.modified = {bool} True 

Но они ничем не отличаются друг от друга.

Есть ли способ поймать только измененные модели?

ответ

2

Вы можете использовать Field.object_data атрибут WTForms':

Это данные, передаваемые от объекта или от kwargs к полю, хранящегося неизмененной. Это может использоваться шаблоны, виджетов, валидаторы по мере необходимости (для сравнения, например)

Таким образом, вы можете сравнить UserNote.body старые и новые значения, а затем изменить автора, если это необходимо, как это:

class ModelFormWithAuthorship(InlineFormAdmin): 
    def on_model_change(self, form, model):  
     # Check whether note's body has changed 
     if form.body.object_data != form.body.data: 
      model.author = User.query.first() 

 Смежные вопросы

  • Нет связанных вопросов^_^