WagtailCMS 中是否有办法对 InlinePanel 中的相关 Orderable 进行验证?

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

我正在使用 Wagtail CMS,我需要对我的

Orderable
模型进行一些验证。就像,确保最多填充一个字段。

通常,我会重写 Django 模型的

clean(self)
方法,但在该方法内调用
super().clean()
将返回
None
。我仍然可以使用
self.field_name
访问字段,并且提高
ValidationError
仍然会阻止创建模型,但它不会显示哪些字段导致管理界面中的模型出现错误。

我尝试覆盖

clean
方法,该方法会阻止模型被提交,但不会在界面上显示错误

我已经尝试遵循指南的这部分,但是甚至没有调用clean

的方法。
这是我的
Orderable

方法的示例

clean

我希望验证错误会显示在管理界面中。
    

我已经深入研究了 wagtail 源代码,我想我找到了如何访问可订购表单控件的方法。
python django validation wagtail
2个回答
2
投票
假设您有一个页面模型,

def clean(self): super().clean() has_image = self.image is not None has_video = self.video_url is not None if has_image == has_video: raise ValidationError('Either a video or an image must be set')

使用一些可订购模型,通过相关名称“test_page_field”链接到页面,

class TestPage(Page): testPageTitle = RichTextField(blank=True, max_length=250) content_panels = Page.content_panels + [ FieldPanel('testPageTitle'), InlinePanel('test_page_field') ] base_form_class = TestPageForm

然后您可以在页面的 clean 方法中通过
class TestPageField(Orderable):
    page = ParentalKey(TestPage, on_delete=models.CASCADE, related_name='test_page_field')

    testPageFieldTitle = models.CharField(blank=True, max_length=250)

    panels = [
    FieldPanel('testPageFieldFieldTitle')
    ]
访问它,这是 Django 表单对象的列表,可以在其中进行常规检查并可以使用

self.formsets['test_page_field'].forms

 方法。相关的 
.add_error()
 如下所示:
base_form_class

我希望这有帮助。
    

这个问题已经有大约 5 年历史了,我最近遇到了这个问题。我想我应该在这里添加官方解决方案以及一些额外的信息,以便人们了解 Orderables 🙌

0
投票
🔥

注意:这是从 Wagtail 6.0 和 Django 5.0 开始更新的。

跳过本文底部以获取完整的代码解决方案。

基本上,您可以像通常使用 Django 模型一样使用

class TestPageForm(WagtailAdminPageForm): def clean(self): cleaned_data = super().clean() #loop over linked orderables for form in self.formsets['test_page_field'].forms: #check first if form is valid, otherwise cleaned_data will not be accesible/set if form.is_valid(): cleaned_form_data = form.clean() testPageFieldFieldTitle = cleaned_form_data.get('testPageFieldFieldTitle') #execute some validation condition, and raise the error if it fails if testPageFieldFieldTitle is None: form.add_error('testPageFieldFieldTitle', 'please dont leave me empty') return cleaned_data

Orderable 对象。在幕后,Orderable 是一个非常普通的 Django 模型,如下所示:

clean()

因为 Orderable 只是一个标准的 Django 模型,所以你可以
class Orderable(models.Model):
    sort_order = models.IntegerField(null=True, blank=True, editable=False)
    sort_order_field = "sort_order"

    class Meta:
        abstract = True
        ordering = ["sort_order"]
(并做其他 Django 的事情)它。

我在 
clean()

方法中添加了额外的

ValidationError

,以便两个字段都会收到验证错误,并且内容编辑者在滚动正在处理的页面时更有可能看到它。
clean()

另请注意,如果您需要验证 Orderable 中
from django.db import models 
from modelcluster.fields import ParentalKey
from wagtail.models import Orderable, Page
from django.core.exceptions import ValidationError
from wagtail.admin.panels import FieldPanel, InlinePanel


class YourOrderableHere(Orderable):
    parental_key = ParentalKey("yourapp.CustomWagtailPage", related_name="custom_orderables")

    image = models.ForeignKey(
        'wagtailimages.Image',
        on_delete=models.CASCADE,
        related_name='+',
    )
    video = models.ForeignKey(
        'yourapp.VideoModel',
        on_delete=models.CASCADE,
        related_name='+',
    )

    panels = [
        FieldPanel("image"),
        FieldPanel("video"),
    ]

    def clean(self) -> None:
        if self.image and self.video
            raise ValidationError({
                'image': ValidationError("You cannot have an image and a video set at the same time"),
                'video': ValidationError("You cannot have an image and a video set at the same time"),
            })
        return super().clean()


class CustomWagtailPage(Page):
    template = ".."
    parent_page_types = []
    subpage_types = []

    content_panels = Page.content_panels + [
        InlinePanel("custom_orderables", label="Add Custom Orderable Item"),
    ]
中的任何数据,您可以通过

CustomWagtailPage

 访问该数据(它将返回整个特定页面实例)。

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