Forms 主模型的创建/编辑视图中的辅助表属性

Forms 主模型的创建/编辑视图中的辅助表属性,forms,python-3.x,flask,many-to-many,flask-admin,Forms,Python 3.x,Flask,Many To Many,Flask Admin,我希望能够在创建或编辑主表的过程中创建和编辑多对多关系的辅助表属性(关系表)。因此,当我编辑一个主表并将关系添加到另一个模型(隐式地使用辅助表)时,我希望能够访问/编辑该辅助关系的属性 更具体地说: 模型 因此,在本例中,我希望能够从flask admin中的纸张和章节的创建/编辑表单中编辑ChapterPaper的“printed”和“note”属性 模型视图 所以,我真的不知道该怎么做。如果我将表单字段添加为附加字段,然后手动验证它们。。。?(我不知道怎么做) 即使如此,向表单中添加额外字段

我希望能够在创建或编辑主表的过程中创建和编辑多对多关系的辅助表属性(关系表)。因此,当我编辑一个主表并将关系添加到另一个模型(隐式地使用辅助表)时,我希望能够访问/编辑该辅助关系的属性

更具体地说:

模型 因此,在本例中,我希望能够从flask admin中的纸张和章节的创建/编辑表单中编辑ChapterPaper的“printed”和“note”属性

模型视图 所以,我真的不知道该怎么做。如果我将表单字段添加为附加字段,然后手动验证它们。。。?(我不知道怎么做)

即使如此,向表单中添加额外字段也不能真正涵盖多个模型。有人能告诉我怎么做吗,或者给我指一个教程,甚至是一些随机项目代码中的相关示例吗


谢谢

好的,这是一项大量的工作,需要大量的RTFM,但一旦开始,它就非常简单了

在没有整洁API的情况下实现这一点的方法是扩展模型视图,并用自己的表单替换创建/编辑表单

这是我的表格课:

class ExtendedPaperForm(FlaskForm):
    title = StringField()
    abstract = TextAreaField()
    doi = StringField()
    pubmed_id = StringField()
    link = StringField()
    journals = QuerySelectMultipleField(
        query_factory=_get_model(Journal),
        allow_blank=False,
    )
    issue = StringField()
    volume = StringField()
    pages = StringField()
    authors = QuerySelectMultipleField(
        query_factory=_get_model(Author),
        allow_blank=False,
    )
    keywords = QuerySelectMultipleField(
        query_factory=_get_model(Keyword),
        allow_blank=True,
    )
    chapters_printed = QuerySelectMultipleField(
        query_factory=_get_model(Chapter),
        allow_blank=True,
        label="Chapters (Printed)",
    )
    chapters = QuerySelectMultipleField(
        query_factory=_get_model(Chapter),
        allow_blank=True,
        label="Chapters (All)",
    )
实现此功能的重要部分是on_model_change方法,它在保存模型之前执行操作

...
    def on_model_change(self, form, model, is_created):
        """
        Perform some actions before a model is created or updated.
        Called from create_model and update_model in the same transaction (if it has any meaning for a store backend).
        By default does nothing.

        Parameters:
        form – Form used to create/update model
        model – Model that will be created/updated
        is_created – Will be set to True if model was created and to False if edited
        """

        all_chapters = list(set(form.chapters.data + form.chapters_printed.data))
        for chapter in all_chapters:

            if chapter in form.chapters_printed.data:  # if chapter in both, printed takes priority
                chapter_paper = ChapterPaper.query.filter_by(chapter_id=chapter.id, paper_id=model.id).first()

                if not chapter_paper:
                    chapter_paper = ChapterPaper(chapter_id=chapter.id, paper_id=model.id)

                chapter_paper.printed = True
                db.session.add(chapter_paper)

        journal = None
        if form.journals.data:
            journal = form.journals.data[0]

        if journal:  # Assumes only 1 journal if there are any journals in this field
            issue = form.issue.data
            volume = form.volume.data
            pages = form.pages.data
            journal_paper = JournalPaper.query.filter_by(journal_id=journal.id, paper_id=model.id).first()

            if not journal_paper:
                journal_paper = JournalPaper(journal_id=journal.id, paper_id=model.id)

            journal_paper.issue = issue
            journal_paper.volume = volume
            journal_paper.pages = pages
            db.session.add(journal_paper)
...

当您创建
纸张
章节
时,请记录
纸张
和``章节之间的记录关联。尝试重新设计您的模型,将
打印的
注释
移动到
纸张
章节
。您可以使用flask-admin的
inline_models
内联管理相关模型。事实上,事实并非如此。将对象添加到任一关系属性时,会自动创建关系对象,因为两者都与“次要”属性连接。不过,使用内联_模型可能会解决我的问题,所以谢谢!
class ExtendedPaperForm(FlaskForm):
    title = StringField()
    abstract = TextAreaField()
    doi = StringField()
    pubmed_id = StringField()
    link = StringField()
    journals = QuerySelectMultipleField(
        query_factory=_get_model(Journal),
        allow_blank=False,
    )
    issue = StringField()
    volume = StringField()
    pages = StringField()
    authors = QuerySelectMultipleField(
        query_factory=_get_model(Author),
        allow_blank=False,
    )
    keywords = QuerySelectMultipleField(
        query_factory=_get_model(Keyword),
        allow_blank=True,
    )
    chapters_printed = QuerySelectMultipleField(
        query_factory=_get_model(Chapter),
        allow_blank=True,
        label="Chapters (Printed)",
    )
    chapters = QuerySelectMultipleField(
        query_factory=_get_model(Chapter),
        allow_blank=True,
        label="Chapters (All)",
    )
...
    def on_model_change(self, form, model, is_created):
        """
        Perform some actions before a model is created or updated.
        Called from create_model and update_model in the same transaction (if it has any meaning for a store backend).
        By default does nothing.

        Parameters:
        form – Form used to create/update model
        model – Model that will be created/updated
        is_created – Will be set to True if model was created and to False if edited
        """

        all_chapters = list(set(form.chapters.data + form.chapters_printed.data))
        for chapter in all_chapters:

            if chapter in form.chapters_printed.data:  # if chapter in both, printed takes priority
                chapter_paper = ChapterPaper.query.filter_by(chapter_id=chapter.id, paper_id=model.id).first()

                if not chapter_paper:
                    chapter_paper = ChapterPaper(chapter_id=chapter.id, paper_id=model.id)

                chapter_paper.printed = True
                db.session.add(chapter_paper)

        journal = None
        if form.journals.data:
            journal = form.journals.data[0]

        if journal:  # Assumes only 1 journal if there are any journals in this field
            issue = form.issue.data
            volume = form.volume.data
            pages = form.pages.data
            journal_paper = JournalPaper.query.filter_by(journal_id=journal.id, paper_id=model.id).first()

            if not journal_paper:
                journal_paper = JournalPaper(journal_id=journal.id, paper_id=model.id)

            journal_paper.issue = issue
            journal_paper.volume = volume
            journal_paper.pages = pages
            db.session.add(journal_paper)
...