Wagtail CMS как проверить содержимое одной страницы перед публикацией или сохранением ее как черновика
Я пытаюсь сделать страницу в Wagtail CMS, которая проверяет содержимое всякий раз, когда я сохраняю/публикую страницу в редакторе администратора.
Содержимое, которое я хочу проверить, это содержимое 3 панелей SnippetChooserPanels внутри страницы. Допустим, у меня есть 3 сниппета: SnippetA, SnippetB и SnippetC, и эти сниппеты (или модели Django, потому что это то, чем они на самом деле являются) имеют следующие отношения:
- СниппетА имеет отношения один ко многим со сниппетомВ
- СниппетВ имеет отношения один ко многим со сниппетомС.
Когда пользователь сохраняет/публикует страницу, я хочу проверить:
- что все 3 типа сниппетов были выбраны
- что между сниппетами существует правильная связь (т.е. сниппетС принадлежит сниппетуВ, а сниппетВ принадлежит сниппетуА, или другими словами 3 сниппета соединены вместе правильно в терминах базы данных SQL)
Спасибо!
Wagtail позволяет вам настроить форму редактирования для каждой из ваших Page
моделей через атрибут base_form_class
на вашей Page
модели.
Класс, на который ссылается эта ссылка, должен быть подклассом WagtailAdminPageForm
. Это Django Form
в своей основе и, следовательно, имеет метод clean
, который позволяет дополнительную пользовательскую валидацию при отправке наряду с неудачным шагом сохранения и предоставлением сообщений об ошибках для каждого поля.
Docs
- Wagtail - настройка интерфейса редактирования
- Django - Валидация форм и полей
Пример кода models.py
from django import forms
from django.db import models
from wagtail.admin.edit_handlers import FieldPanel
from wagtail.admin.forms import WagtailAdminPageForm
from wagtail.core.models import Page
from wagtail.snippets.edit_handlers import SnippetChooserPanel
class CustomPageForm(WagtailAdminPageForm):
def clean(self):
cleaned_data = super().clean()
# Make sure that the the snippets relate to each other correctly
snippet_a = cleaned_data['snippet_a']
snippet_b = cleaned_data['snippet_b']
snippet_c = cleaned_data['snippet_c']
# example validation only - you will need to work this out based on your exact requirements
if snippet_a.pk is snippet_b.pk:
self.add_error('snippet_a', 'The snippets must be different')
if snippet_b.pk is snippet_c.pk:
self.add_error('snippet_a', 'The snippets must be different')
if snippet_c.pk is snippet_a.pk:
self.add_error('snippet_a', 'The snippets must be different')
if snippet_c.pk is snippet_b.pk:
self.add_error('snippet_a', 'The snippets must be different')
return cleaned_data
class EventPage(Page):
# note: actual models.ForeignKey usage not added, just for the example
snippet_a = models.ForeignKey()
snippet_b = models.ForeignKey()
snippet_c = models.ForeignKey()
content_panels = [
SnippetChooserPanel('snippet_a'),
SnippetChooserPanel('snippet_b'),
SnippetChooserPanel('snippet_c'),
]
base_form_class = CustomPageForm