Python 如何在wagtail管理中修改页面模型视图?

Python 如何在wagtail管理中修改页面模型视图?,python,django,wagtail,Python,Django,Wagtail,背景:我想在管理页面视图中使用一些与管理请求相关的信息(通常是一些预填充)来增强页面实例。基本上,我需要一些像“get_queryset”这样的函数,但不是用于列表视图,只是用于编辑视图 在我以前的问题中,我遇到了一个类似的问题:有人向我提供了使用名为 创建页面视图 但是,我无法导入它。此外,如果我搜索,我甚至在谷歌上找不到任何关于这一点的提及: Wagtail+CreatePageView 我找到的最接近的东西是,但该页面还指出: 注意:modeladmin仅提供“创建”、“编辑”和“删除”

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

在我以前的问题中,我遇到了一个类似的问题:有人向我提供了使用名为

创建页面视图

但是,我无法导入它。此外,如果我搜索,我甚至在谷歌上找不到任何关于这一点的提及:

Wagtail+CreatePageView

我找到的最接近的东西是,但该页面还指出:

注意:modeladmin仅提供“创建”、“编辑”和“删除” 非页面类型模型(即不扩展的模型)的功能 wagtailcore.models.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?
编辑

正如评论中所建议的,可以在创建过程中修改管理员页面表单:

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构造函数中获取“请求”似乎是不可能的。

这个问题有点含糊不清,因此不太清楚您到底需要什么

解释性问题:当计入(或编辑)页面时,我需要访问
请求
,以修改页面表单中某些字段的初始值。

潜在途径 注意:这可能不是最佳实践,并且可能很脆弱,这取决于对Wagtail的未来更改

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

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

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

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

示例代码
从wagtail.admin.edit\u处理程序导入选项卡界面,对象列表
从wagtail.core.models导入页面
类CustomTabbedInterface(TabbedInterface):
def get_form_类(自我):
form\u class=super().获取\u form\u class()
请求=自我请求
if request和request.method!='邮政‘’
#检查请求可用,以确保此实例已绑定到它
user=self.request.user
def启动_类(**kwargs):
#不是返回类,而是返回一个返回实例化类的函数
#这里我们可以在生成的表单中插入一个kwarg'initial'
#重要提示:对于“编辑视图”也会调用此命令,并且initial将覆盖实例数据
#kwarg['instance']将是'Page'实例,可以根据需要进行检查
kwargs['initial']={'introduction':user.first_name}
报税表(类别(**kwargs)
返回初始化类
报税表
班级标准页面(第页):
# ... 场等
编辑\处理程序=自定义选项卡界面([
对象列表(内容面板,标题='content'),
ObjectList(Page.promote_面板,标题='promote'),
ObjectList(Page.settings_面板,heading='settings',classname='settings'),
])
解释
  • 包含
    create
    视图,该视图将使用
    edit\u处理程序
    ,将其绑定到模型和请求,然后调用其
    get\u form\u类
  • 此处的响应使用
    表单\u类
  • 使用实例和父页面kwargs调用它
  • 我们的定制
    get\u form\u类
    响应接受这些kwarg并注入额外的
    initial
    kwarg
  • initial
    由Django表单用于添加任何初始数据-
  • 最后,Django表单将实例字段值与
    initial
    kwarg合并,以生成表单的最终预填充数据。您可以在中看到这是如何工作的
  • <> LI>仔细考虑在更新视图中会发生什么,当用户已经输入了字段中的某个内容时,您可能不希望用初始值重写现有值。
您能否给出一个您想要覆盖的具体示例?根据您的提问,听起来您想更改外键选择的查询集?@IainShelvington我的问题是,当在admin中向用户显示页面时,我应该覆盖哪些内容来修改页面。ModelAdmin可能不是您想要的,这可能有点令人困惑,因为ModelAdmin确实提供了一种管理/编辑页面的方法,但它不是主要的方法。也许是你需要的?@LBBenJohnston好主意,谢谢你的努力。我以前不知道这个选项。然而,这还不够——我修改了我的问题以反映你的想法。干得好!它适用于Wagtail2.9。注意:它不适用于Wagtail 2.4(self.request不存在)。很高兴知道。在过去的一段时间里,这一领域的代码一直在不断变化。那是可能的