【问题标题】:How to modify Page model view in wagtail admin?如何在 wagtail 管理员中修改页面模型视图?
【发布时间】:2020-05-10 15:42:09
【问题描述】:

背景:我想在管理页面视图期间使用一些与管理请求相关的信息(通常是一些预填充)来增强页面实例。基本上我需要一些像“get_queryset”这样的函数,但不是用于列表视图,只是用于编辑视图。

在与类似问题相关的较早问题中:Wagtail - how to preopulate fields in admin form? 向我提供了使用名为

的东西的说明

创建页面视图

但是,我无法导入它。此外,如果我搜索,我什至在谷歌中找不到任何提及:

鹡鸰+CreatePageView

我找到的最接近的东西是https://docs.wagtail.io/en/v2.1.1/reference/contrib/modeladmin/create_edit_delete_views.html,但该页面还指出:

注意:modeladmin 仅提供“create”、“edit”和“delete” 非页面类型模型的功能(即不扩展的模型 wagtailcore.models.Page)。如果您的模型是“页面类型”模型, 自定义以下任何一项都不会产生任何影响

我很困惑。如果我需要为 Page 模型扩展自定义管理视图,我应该怎么做?

我研究了 Model.admin 和 Page 的 wagtail 源代码,但没有找到任何方法。有什么想法吗?

相关代码简化:

鹡鸰钩:

class ItemAdmin(ModelAdmin):

    pass

    # some function override here maybe?

型号:

class ItemPage(Page):

    pass

    # override for a function that gives data to the admin view maybe here?

编辑

按照 cmets 的建议,可以在创建过程中修改管理页面表单:

from wagtail.admin.forms import WagtailAdminPageForm

class ItemPageForm(WagtailAdminPageForm):

    def __init__(self, data=None, files=None, parent_page=None, *args, **kwargs):
        super().__init__(data, files, *args, **kwargs)


class ItemPage(Page):

    base_form_class = ItemPageForm

但是,在 WagtailAdminPageForm 构造函数中获取“请求”似乎是不可能的。

【问题讨论】:

  • 你能举一个你想要覆盖的例子吗?从您所问的内容看来,您想更改外键选择的查询集?
  • @IainShelvington 我的问题是关于在管理员中向用户显示页面时我应该覆盖什么来修改页面。
  • ModelAdmin 可能不是您想要的,它可能有点令人困惑,因为 ModelAdmin 确实提供了一种管理/编辑页面的方法,但它不是主要方式。 docs.wagtail.io/en/stable/advanced_topics/customisation/… 可能是您需要的?
  • @LBBenJohnston 好主意,感谢您的努力。我以前不知道这个选项。但是,这还不够 - 我修改了我的问题以反映您的想法。

标签: python django wagtail


【解决方案1】:

这个问题有点模棱两可,所以不是很清楚你到底需要什么。

问题解读:在添加(或编辑)页面时,我需要访问request 来修改页面表单中某些字段的初始值。

可能的方法

注意:这可能不是最佳做法,并且可能会很脆弱,具体取决于 Wagtail 未来的变化。

首先,我们需要一个自定义的EditHandler,这是 Wagtail 在编辑界面中构建表单甚至面板的方式。 EditHandler 的工作是根据模型甚至当前请求管理要返回的表单。

作为第一步,最好按照有关使用自定义选项卡式界面的说明正确显示您的页面创建表单。从这里,您可以将TabbedInterface 替换为您的自定义类(例如CustomTabbedInterface),并为此添加一些功能,以便返回动态form_class

get_form_class 应该返回form_class,但是,我们可以修改它以返回一个函数,该函数在调用时将根据请求使用自定义信息实例化类。

在此示例未考虑的编辑视图或场景中,此方法可能存在一些问题,因此请在使用前充分验证。

示例代码

from wagtail.admin.edit_handlers import TabbedInterface, ObjectList
from wagtail.core.models import Page

class CustomTabbedInterface(TabbedInterface):

    def get_form_class(self):
        form_class = super().get_form_class()
        request = self.request
        if request and request.method != 'POST':
            # check request is available to ensure this instance has been bound to it
            user = self.request.user

            def initiate_class(**kwargs):
                # instead of returning the class, return a function that returns the instantiated class
                # here we can inject a kwarg `initial` into the generated form
                # important: this gets called for edit view also and initial will override the instance data
                # kwarg['instance'] will be the `Page` instance and can be inspected as needed
                kwargs['initial'] = {'introduction': user.first_name}

                return form_class(**kwargs)

            return initiate_class

        return form_class


class StandardPage(Page):
    # ... field etc
    edit_handler = CustomTabbedInterface([
        ObjectList(content_panels, heading='Content'),
        ObjectList(Page.promote_panels, heading='Promote'),
        ObjectList(Page.settings_panels, heading='Settings', classname="settings"),
    ])

说明

【讨论】:

  • 干得好!它适用于 Wagtail 2.9。注意:它不适用于 Wagtail 2.4(self.request 不存在)。
  • 很高兴知道。在过去的一段时间里,该代码领域一直在变化。这可能就是您链接的其他问题回复不起作用的原因。
猜你喜欢
  • 1970-01-01
  • 2021-11-30
  • 1970-01-01
  • 2017-10-22
  • 2021-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-27
相关资源
最近更新 更多