我正在使用 Wagtail CMS,我需要对我的
Orderable
模型进行一些验证。就像,确保最多填充一个字段。
通常,我会重写 Django 模型的
clean(self)
方法,但在该方法内调用 super().clean()
将返回 None
。我仍然可以使用 self.field_name
访问字段,并且提高 ValidationError
仍然会阻止创建模型,但它不会显示哪些字段导致管理界面中的模型出现错误。
我尝试覆盖
clean
方法,该方法会阻止模型被提交,但不会在界面上显示错误
我已经尝试遵循指南的这部分,但是甚至没有调用clean
的方法。
这是我的
Orderable
方法的示例
clean
我希望验证错误会显示在管理界面中。我已经深入研究了 wagtail 源代码,我想我找到了如何访问可订购表单控件的方法。
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 🙌
注意:这是从 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
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
访问该数据(它将返回整个特定页面实例)。