自定义 WagtailAdminPageForm 的保存方法多次调用,即使在页面加载时也是如此:How to trigger custom save action only on save?

问题描述 投票:0回答:1

我想在页面保存时基于另一个编辑器填充的字段为鹡鸰页面模型自动生成字段内容。

我遵循了 wagtail 文档,我能够在页面保存/发布时以编程方式填充和保存字段:

from wagtail.models import Page
from wagtail.admin.forms import WagtailAdminPageForm

class TestPageForm(WagtailAdminPageForm):
    def clean(self):
        cleaned_data = super().clean()
        print("-> called TestPageForm.clean()")
        return cleaned_data

    def save(self, commit=True):
        print(f"1 {commit=}")
        page = super().save(commit=False)
        print(f"2 {commit=}")
        print("-> called TestPageForm.save()")
        # process something, save result to instance field, e.g.:
        # page.pdf_cover_image = get_cover_image(self.cleaned_data["pdf"])

        if commit:
            print(f"{commit=}: calling page.save()")
            page.save()

        return page


class TestPage(Page):
    base_form_class = TestPageForm

但是形式

clean()
save()
方法被多次调用,即使我根本没想到它们会被调用:

编辑页面

通过 wagtail 后端(“编辑页面”)请求页面实例:

http://127.0.0.1:8000/admin/pages/139/edit/

[10/May/2023 10:35:37] "GET /admin/pages/139/edit/ HTTP/1.1" 200 71082
[...assets...]
-> called TestPageForm.clean()
1 commit=False
2 commit=False
-> called TestPageForm.save()
[10/May/2023 10:35:37] "GET /admin/pages/139/edit/preview/?in_preview_panel=true&mode= HTTP/1.1" 200 0
[10/May/2023 10:35:37] "DELETE /admin/pages/139/edit/preview/ HTTP/1.1" 200 17
-> called TestPageForm.clean()
[10/May/2023 10:35:37] "POST /admin/pages/139/edit/preview/ HTTP/1.1" 200 40
-> called TestPageForm.clean()
1 commit=False
-> called TestPageForm.clean()
2 commit=False
-> called TestPageForm.save()
1 commit=False
2 commit=False
-> called TestPageForm.save()
[10/May/2023 10:35:37] "GET /admin/pages/139/edit/preview/?in_preview_panel=true&mode= HTTP/1.1" 200 0

保存页面

[10/May/2023 10:35:37] "GET /admin/pages/139/edit/preview/?in_preview_panel=true&mode= HTTP/1.1" 200 0
-> called TestPageForm.clean()
1 commit=False
2 commit=False
-> called TestPageForm.save()
[10/May/2023 10:38:10] "POST /admin/pages/139/edit/ HTTP/1.1" 302 0
[10/May/2023 10:38:10] "GET /admin/pages/8/ HTTP/1.1" 200 45356

所以在页面上保存表格

clean()
save()
方法只被调用一次 - 但因为
commit
总是
False
我无法区分所有这些清洁和保存调用......

那么我如何触发一个自定义的 save()-action,它只会被调用一次并且只在页面 save() 上被调用?

django wagtail wagtail-admin
1个回答
0
投票

如果您使用的是 Wagtail 4+,那么无论它是否可见,预览面板都会调用清理/保存(这不应该发生在 IMO 上,但现在就是这样)。

因此,当我升级时,我需要将一些繁重的字段计算代码移出干净。我在创建/编辑挂钩后使用

@hooks.register("after_edit_page")
@hooks.register("after_create_page")
def get_something(request, page):
    if page.specific_class == SomePage:
        try:
            page.something = calculate_something()
            if page.has_unpublished_changes:
                page.save_revision()
            else:
                page.save()
        except Exception as e:
            print(f"{type(e).__name__} at line {e.__traceback__.tb_lineno} of {__file__}: {e}")       
            messages.error(request, _('There was a problem generating the something'))

这只会在编辑器单击保存/保存草稿时触发,他们需要这样做才能在实时预览中查看影响此计算的更改的任何渲染效果。

© www.soinside.com 2019 - 2024. All rights reserved.