【问题标题】:Problem with adding new instance to DB with Flask-Admin [duplicate]使用 Flask-Admin 将新实例添加到数据库时出现问题 [重复]
【发布时间】:2022-01-08 09:05:59
【问题描述】:

我在使用 flask-admin 添加新实例时遇到了一点问题。 我的模型是:

class MenuCategory(db.Model):

    id = db.Column(db.Integer, primary_key=True)
    name_category = db.Column(db.String(20), unique=True)
    slug = db.Column(db.String(255))
    order = db.Column(db.Integer)
    path = db.Column(db.Unicode(128))

    def __init__(self, **kwargs):
        if not 'slug' in kwargs:
            kwargs['slug'] = slugify(kwargs.get('name_category', ''))
        super().__init__(**kwargs)

    def __repr__(self):
        return f'<Category {self.name_category}>'

ModelView 也是:

class MenuCategoryView(ModelView):

    column_labels = dict(name_category='Наименование категории', order='Приоритет', path='Изображение')
    column_editable_list = ('name_category', 'order')
    column_default_sort = 'order'
    form_excluded_columns = ('slug')

当我在其中创建新实例时也应该添加“slug”值。它在带有烧瓶壳的终端中运行良好:

>>> m = MenuCategory(name_category='Something here')
{'name_category': 'Something here', 'slug': 'something-here'}
>>> db.session.add(m)
>>> db.session.commit()

但是当我使用 flask-admin 创建新实例时,它只是添加一个没有“slug”和 NULL 值的新实例。谁能告诉我我做错了什么?

【问题讨论】:

  • 我采用 Liran BG 解决方案从stackoverflow.com/questions/23657483/slug-field-on-flask 制作 slug,现在它可以工作了 有人可以解释一下区别吗?
  • 一个建议,当您编辑您的问题时,它会再次出现在顶部,因此得到回答的机会要大得多

标签: python flask flask-sqlalchemy flask-admin


【解决方案1】:

如果我们查看flask-admin代码,我们可以在创建模型时看到这样的部分:

    def create_model(self, form):
        try:
            # It calls __new__ of model
            model = self._manager.new_instance()
            # TODO: We need a better way to create model instances and stay compatible with
            # SQLAlchemy __init__() behavior
            # Next two lines fill the special _sa_instance_state of model
            state = instance_state(model)
            self._manager.dispatch.init(state, [], {})

            # populate_obj is probably as simple as model.field1 = form.field1 and so on
            form.populate_obj(model)
            self.session.add(model)
            self._on_model_change(form, model, True)
            self.session.commit()

所以甚至没有调用甚至有 TODO 注释的 init(但是它是在两年前添加的,所以我很确定根本不会解决)。

不同之处在于,添加事件侦听器时,您实际上会侦听与数据库本身交互时发生的事件,例如,当设置特定字段时(因此在我们的例子中,当 form.populate_obj 将分配 model.name_category = ...)时,发生的总是不同拨打__init__

【讨论】:

    猜你喜欢
    • 2019-04-16
    • 1970-01-01
    • 2020-07-11
    • 2021-05-29
    • 2015-12-02
    • 1970-01-01
    • 2021-08-22
    • 2021-11-25
    • 2017-07-30
    相关资源
    最近更新 更多