Python Flask Admin中的简单多对多问题

Python Flask Admin中的简单多对多问题,python,flask,flask-sqlalchemy,flask-admin,Python,Flask,Flask Sqlalchemy,Flask Admin,我正在将Flask Admin添加到现有的Flask应用程序中(使用Python3和带有SQLAlchemy的MySQL),我根本不知道如何获得正确呈现的多对多关系。我在这里读了很多关于这方面的问题,看起来我遵循了正确的做法 我有一个quote表、一个Subject表和一个QuotationSubject表,它必须是一个实际的类,而不是一个关联表,但我不关心关联表中为此目的的额外列;它们是我不需要显示或编辑的last\u modified。这些关系似乎在应用程序的其余部分中起作用 删掉这里不重要

我正在将Flask Admin添加到现有的Flask应用程序中(使用Python3和带有SQLAlchemy的MySQL),我根本不知道如何获得正确呈现的多对多关系。我在这里读了很多关于这方面的问题,看起来我遵循了正确的做法

我有一个
quote
表、一个
Subject
表和一个
QuotationSubject
表,它必须是一个实际的类,而不是一个关联表,但我不关心关联表中为此目的的额外列;它们是我不需要显示或编辑的
last\u modified
。这些关系似乎在应用程序的其余部分中起作用

删掉这里不重要的字段和定义,我有:

课堂报价(db.Model):
__tablename_uu='quote'
id=db.Column(db.Integer,主键=True)
word=db.Column(db.String(50))
description=db.Column(db.Text)
created=db.Column(db.TIMESTAMP,默认值=db.func.now())
last_modified=db.Column(db.DateTime,server_default=db.func.now())
subject=db.关系(“QuotationSubject”,back_populates=“quote”)
定义(自我):
返回自我单词
课程主题(数据库模型):
__tablename_uu='subject'
id=db.Column(db.Integer,主键=True)
name=db.Column(db.String(50))
created=db.Column(db.TIMESTAMP,默认值=db.func.now())
last_modified=db.Column(db.DateTime,server_default=db.func.now())
QUOTE=db.关系(“QuotationSubject”,back_populates=“subject”)
定义(自我):
返回self.name
类报价主题(数据库模型):
__tablename\uuuu='quote\u subject'
id=db.Column(db.Integer,主键=True)
QUOTE_id=db.Column(db.Integer,db.ForeignKey('QUOTE.id'),默认值=0,null=False)
subject_id=db.Column(db.Integer,db.ForeignKey('subject.id'),默认值=0,null=False)
created=db.Column(db.TIMESTAMP,默认值=db.func.now())
last_modified=db.Column(db.DateTime,server_default=db.func.now())
QUOTE=db.relationship('QUOTE',back_populates='subject',lazy='joined')
subject=db.relationship('subject',back_populates='quote',lazy='joined')
在我的
admin.py
中,我只有:

class QuotationModelView(ModelView):
列\u可搜索\u列表=['word','description']
表单_排除_列=[“已创建”、“上次_修改”]
列列表=('word','subject')
管理员添加视图(QuotationModelView(Quotation,db.session))
就这样

在我的
列表
视图中,我没有看到
主题
值,而是在
QuotationSubject
表中获取相关条目,例如

test    <QuotationSubject 1>, <QuotationSubject 17>, <QuotationSubject 18>
book    <QuotationSubject 2>
测试,
书
类似地,在我的
create
视图中,我没有得到一个包含十几个主题的列表,而是从QuotationSubject表中得到了一个包含所有内容的庞大列表


我已经看了一些
inline_模型
的东西,这里的一些帖子建议,这些东西也没有用,但是在任何情况下,也有其他帖子(例如)建议我所做的应该有用。如果有人能指出我做错了什么,我将不胜感激

首先,我担心你的问题遗漏了什么,因为我没有看到
引文
类的定义。但这似乎不是问题所在

Flask中多对多关系的最经典示例是用户角色。以下是工作角色与用户M2M的关系:

class RolesUsers(Base):
    __tablename__ = 'roles_users'

    id = db.Column(db.Integer(), primary_key=True)
    user_id = db.Column(db.Integer(), db.ForeignKey('user.id'))
    role_id = db.Column(db.Integer(), db.ForeignKey('role.id'))

class Role(RoleMixin, Base):
    __tablename__ = 'role'

    id = db.Column(db.Integer(), primary_key=True)
    name = db.Column(db.String(80), unique=True)

    def __repr__(self):
        return self.name

class User(UserMixin, Base):
    __tablename__ = 'user'

    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(120), index=True, unique=True)

    roles = db.relationship('Role', secondary='roles_users',
                            backref=db.backref('users', lazy='dynamic'))
在这方面:

from user.models import User, Role

admin.add_view(PVCUserView(User, db.session))
admin.add_view(PVCModelView(Role, db.session))
请注意,该关系只声明一次,带有
backref
,因此它是双向的。看起来您正在为此使用
back\u populates
,这是一个错误

对于您正在描述的情况,代码似乎直接向M2M表声明了关系。这真的是你想要的吗?您说您不需要访问Flask Admin的QuotationSubject表中的额外列。但是你在别处需要它们吗?对我来说,调用
quote
subject
实际上返回
QuotationSubject
的一个实例似乎很奇怪。我相信这就是Flask Admin在create视图中列出所有QuotationSubject行的原因

因此,我的建议是尝试将您的关系设置为直接指向目标模型类,同时将M2M表作为
第二个

如果您想在其他地方访问关联模型(如果由于某种原因它确实不能成为一个),那么在每个模型类中创建第二个显式指向它的关系。然后,您可能需要在Flask Admin中使用
form\u excluded\u columns
column\u excluded\u list

排除该关系,非常感谢。“引文”是“引文”的拼写错误;我不得不重新输入其中一些;我在编辑中修复了它。对于关系问题,我试图非常密切地遵循SQLA文档中的多对多准则,位于。对于关联对象示例,它确实显示了与M2M表的连接,但如果重新读取它,则这并不是命中另一侧模型的主要方式。我会做出调整;谢谢你的指点!