Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Flask admin:捕获内联模型上的更改_Python_Flask_Flask Wtforms_Flask Admin - Fatal编程技术网

Python Flask admin:捕获内联模型上的更改

Python Flask admin:捕获内联模型上的更改,python,flask,flask-wtforms,flask-admin,Python,Flask,Flask Wtforms,Flask Admin,我有一个简单的应用程序,完整的代码介绍。它使用flask admin 模型: 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.

我有一个简单的应用程序,完整的代码介绍。它使用flask admin

模型:

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的作者。对于当前登录的用户来说,这是一种简化

但是flask管理员将所有内联模型传递给此方法

以下是报告的步骤

  • 启动应用程序
  • 创建名为user1的用户(此用户可能是第一个()
  • 创建名为admin1的用户
  • 创建名为admin2的用户
  • 创建2个内联注释,将user1作为作者
  • 直接连接到数据库,将其中一个注释的作者更改为admin1,将另一个注释的作者更改为admin2
  • 转到Flask管理员,确保您有来自2个用户的2条注释
  • 编辑第一个注释的正文,然后单击“保存”
  • 对于我来说,这些操作的预期结果是,第一个注释的作者将是user1,第二个注释的作者将保持不变。 但是实际结果如下:author for two notes设置为user1

    我尝试过调试,发现了一些有趣的属性:

    # 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
    
    但它们彼此无法区分

    是否有办法仅捕获已更改的模型?

    您可以使用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()