首页 > 解决方案 > 在烧瓶管理中插入两个模型的一种形式

问题描述

我使用 flask-admin 和 flask-sqlalchemy 作为一个简单的管理界面来在我们的数据库/flask 应用程序中创建和编辑项目。

我们有两个模型,一个是父母,一个是孩子。目前我们的流程是:

  1. 创建一个没有子项的新父项
  2. 创建一个新的孩子并设置孩子的父母

为了节省时间,我想要一个用于创建新父级的表单,我们可以在其中输入父级和子级的所有详细信息并创建父级,然后创建子级,在子级和父级之间设置一个外键创建的。

有没有办法用烧瓶管理员做到这一点?

标签: pythonflaskflask-admin

解决方案


你试过 Flask Admininline models吗?

这是一个具有一对多关系的示例。不幸的是,FlaskAdmin 不提供对一对多关系的完整支持(来源)。

目前,它仅支持在关系的“一”侧提供内联模型。给定两个模型:PostGuide, where one guide has many posts,你会得到这样的东西:

from flask import Flask
from flask_admin import Admin
from flask_admin.contrib.sqla import ModelView
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///storage.sqlite3'
app.secret_key = 'secret'

db = SQLAlchemy(app)

# defining the "one" side of the relationship
class Guide(db.Model):
    __tablename__ = "guides"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255), nullable=False, unique=True)
    description = db.Column(db.String(512), nullable=False)

    posts = db.relationship("Post", back_populates="guide")

# defining the "many" side of the relationship
class Post(db.Model):
    __tablename__ = "posts"
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(255), nullable=False)
    content = db.Column(db.Text, nullable=False)

    guide_id = db.Column(
        db.Integer, db.ForeignKey("guides.id", ondelete="CASCADE"), nullable=False
    )
    guide = db.relationship("Guide", back_populates="posts")
    

db.create_all()
    
    
admin = Admin(app, template_mode="bootstrap3")

# creating a custom model view for the Guide model.
class ModelViewWithInlineModel(ModelView):
    # here you provide a tuple with the inline models you want to
    # render to the user
    inline_models = (Post,)

# using FlaskAdmin ModelView default implementation for the Post model
admin.add_view(ModelView(Post, db.session))
# using our custom ModelView with the Post as an inline model
admin.add_view(ModelViewWithInlineModel(Guide, db.session))


if __name__ == '__main__':
    app.run(debug=True)

推荐阅读