Flask-Admin 在代理关联中添加新关键字

Posted

技术标签:

【中文标题】Flask-Admin 在代理关联中添加新关键字【英文标题】:Flask-Admin Adding new Keyword in Proxy Association 【发布时间】:2022-01-21 23:07:18 【问题描述】:

有谁知道使用 flask-admin 实现以下目标的最佳方法

我有两个模型 User 和 Keyword 有一对多的关系。

我想做的是在创建或编辑表单中允许用户选择可用关键字或在创建用户视图中添加新关键字。

目前我能够实现其中之一,但不能同时实现。

使用内联模型,我可以允许用户在为用户创建视图中添加新关键字,但关键字字段将被覆盖。不使用内联模型时,flask-admin 正确显示 Select2Field 允许用户从关键字模型中选择多个关键字。



class User(db.Model):
    __tablename__ = 'user'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64))

    # Association proxy of "user_keywords" collection to "keyword" attribute - a list of keywords objects.
    keywords = association_proxy('user_keywords', 'keyword')
    # Association proxy to association proxy - a list of keywords strings.
    keywords_values = association_proxy('user_keywords', 'keyword_value')

    def __init__(self, name=None):
        self.name = name


class UserKeyword(db.Model):
    __tablename__ = 'user_keyword'
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
    keyword_id = db.Column(db.Integer, db.ForeignKey('keyword.id'), primary_key=True)
    special_key = db.Column(db.String(50))

    # bidirectional attribute/collection of "user"/"user_keywords"
    user = relationship(User, backref=backref("user_keywords", cascade="all, delete-orphan"))

    # reference to the "Keyword" object
    keyword = relationship("Keyword")
    # Reference to the "keyword" column inside the "Keyword" object.
    keyword_value = association_proxy('keyword', 'keyword')

    def __init__(self, keyword=None, user=None, special_key=None):
        self.user = user
        self.keyword = keyword
        self.special_key = special_key


class Keyword(db.Model):
    __tablename__ = 'keyword'
    id = db.Column(db.Integer, primary_key=True)
    keyword = db.Column('keyword', db.String(64))

    def __init__(self, keyword=None):
        self.keyword = keyword

    def __repr__(self):
        return 'Keyword(%s)' % repr(self.keyword)




class UserAdmin(sqla.ModelView):
    """ Flask-admin can not automatically find a association_proxy yet. You will
        need to manually define the column in list_view/filters/sorting/etc.
        Moreover, support for association proxies to association proxies
        (e.g.: keywords_values) is currently limited to column_list only."""

    column_list = ('id', 'name', 'keywords', 'keywords_values')
    column_sortable_list = ('id', 'name')
    column_filters = ('id', 'name', 'keywords')
    form_columns = ('name', 'keywords')


class KeywordAdmin(sqla.ModelView):
    column_list = ('id', 'keyword')

【问题讨论】:

您必须输入最少的代码才能让人们帮助您。否则非常复杂。你的模型看起来怎么样? Flask-admin 怎么称呼? 谢谢,我已经用精简版的代码更新了这个问题。 【参考方案1】:

所以我一直在研究这个并想出了一个答案,并认为我会在这里分享它以防有人感兴趣。

在我的 ModelView 中我写了一个 ajax 函数。

  @expose('/ajax/add_keyword/', methods=('POST',))
    def ajax_add_category(self):


        if Keyword.query.filter_by(keyword=request.form.get('keyword')).first():
            return 'Already exist', 500

        keyword = Keyword(keyword=request.form.get('category'))

     
    
        db.session.add(keyword)
        db.session.commit()
        return jsonify('id': keyword.id, 'text': keyword.keyword)

在我的 edit_view 和 create_view 中,我添加了一个简单的 JQuery 并触发了 Select2 触发器。


 <label for="keyword">Keyword</label>
      <input type="text" name="keyword">
      <input class='add_keyword' type="submit" value="Add">
     


<script>

    $('.add_keyword').click( function() 

        category = $('[name="keyword"]');
        $.post(" get_url('.ajax_add_keyword') ", 
              
                keyword : keyword.val() ,
               , function(data, status) 
                var newOption = new Option(data.text, data.id, false, true);
                $('#categories').append(newOption).trigger('change');
        );
    );
  </script>

这是一个快速而肮脏的解决方案,但可以清理以看起来更整洁。

【讨论】:

以上是关于Flask-Admin 在代理关联中添加新关键字的主要内容,如果未能解决你的问题,请参考以下文章

Flask-Admin column_formatters 未调用

在 Flask-Admin 中替换 Jquery Select2?

如何在 Flask-Admin 中显示参考字段的实际字段?

如何在新签名字段中关联先前的签名

设计模式-代理模式(结构)装饰模式(结构)

使用 SQLAlchemy 关联代理强制唯一性