Warn if StreamField doesn't use StreamFieldPanel (#7276)

pull/7288/head
nmorduch 2021-06-22 11:24:54 -04:00 zatwierdzone przez Matt Westcott
rodzic 2b8049fbd4
commit 368049b835
4 zmienionych plików z 75 dodań i 2 usunięć

Wyświetl plik

@ -11,6 +11,7 @@ Changelog
* Added locale selector when choosing translatable snippets (Karl Hobley)
* Added `WAGTAIL_WORKFLOW_ENABLED` setting for enabling / disabling moderation workflows globally (Matt Westcott)
* Allow specifying `max_width` and `max_height` on EmbedBlock (Petr Dlouhý)
* Add warning when StreamField is used without a StreamFieldPanel (Naomi Morduch Toubman)
* Fix: Invalid filter values for foreign key fields in the API now give an error instead of crashing (Tidjani Dia)
* Fix: Ordering specified in `construct_explorer_page_queryset` hook is now taken into account again by the page explorer API (Andre Fonseca)
* Fix: Deleting a page from its listing view no longer results in a 404 error (Tidjani Dia)

Wyświetl plik

@ -19,6 +19,7 @@ Other features
* Added locale selector when choosing translatable snippets (Karl Hobley)
* Added ``WAGTAIL_WORKFLOW_ENABLED`` setting for enabling / disabling moderation workflows globally (Matt Westcott)
* Allow specifying ``max_width`` and ``max_height`` on EmbedBlock (Petr Dlouhý)
* Add warning when StreamField is used without a StreamFieldPanel (Naomi Morduch Toubman)
Bug fixes
~~~~~~~~~

Wyświetl plik

@ -1,6 +1,7 @@
import os
from django.core.checks import Error, Warning, register
from django.core.exceptions import FieldDoesNotExist
@register()
@ -151,3 +152,51 @@ There are no default tabs on non-Page models so there will be no \
errors.append(error)
return errors
@register('panels')
def panel_type_check(app_configs, **kwargs):
from wagtail.core.models import get_page_models
errors = []
for cls in get_page_models():
errors += traverse_edit_handlers(cls.get_edit_handler())
return errors
def traverse_edit_handlers(edit_handler):
errors = []
try:
for child in edit_handler.children:
errors += traverse_edit_handlers(child)
except AttributeError:
error = check_stream_field_panel_type(edit_handler)
if error:
errors.append(error)
return errors
def check_stream_field_panel_type(edit_handler):
from wagtail.admin.edit_handlers import StreamFieldPanel
from wagtail.core.fields import StreamField
try:
db_field = getattr(edit_handler, 'db_field', None)
if isinstance(db_field, StreamField) and not isinstance(edit_handler, StreamFieldPanel):
return Warning(
"{model}.{field_name} is a StreamField, but uses {edit_handler}".format(
model=edit_handler.model.__name__,
field_name=edit_handler.field_name,
edit_handler=edit_handler.__class__.__name__),
hint="Ensure that it uses a StreamFieldPanel, or change the field type",
obj=edit_handler.model,
id='wagtailadmin.W003'
)
except FieldDoesNotExist:
# Doesn't check any fields not on the model, such as in
# wagtail.tests.testapp.modelsFormClassAdditionalFieldPage
pass

Wyświetl plik

@ -24,8 +24,8 @@ from wagtail.core.models import Comment, CommentReply, Page, Site
from wagtail.images.edit_handlers import ImageChooserPanel
from wagtail.tests.testapp.forms import ValidatedPageForm
from wagtail.tests.testapp.models import (
EventPage, EventPageChooserModel, EventPageSpeaker, PageChooserModel, RestaurantPage,
RestaurantTag, SimplePage, ValidatedPage)
DefaultStreamPage, EventPage, EventPageChooserModel, EventPageSpeaker, PageChooserModel,
RestaurantPage, RestaurantTag, SimplePage, ValidatedPage)
from wagtail.tests.utils import WagtailTestUtils
@ -217,6 +217,28 @@ class TestPageEditHandlers(TestCase):
self.assertEqual(errors, [invalid_base_form, invalid_edit_handler])
@clear_edit_handler(DefaultStreamPage)
def test_check_invalid_streamfield_edit_handler(self):
"""
Set the edit handler for body (a StreamField) to be
a FieldPanel instead of a StreamFieldPanel.
Check that the correct warning is raised.
"""
invalid_edit_handler = checks.Warning(
"DefaultStreamPage.body is a StreamField, but uses FieldPanel",
hint="Ensure that it uses a StreamFieldPanel, or change the field type",
obj=DefaultStreamPage,
id='wagtailadmin.W003')
with mock.patch.object(DefaultStreamPage, 'content_panels', new=[FieldPanel('body')]):
checks_result = checks.run_checks(tags=['panels'])
# Only look at warnings for DefaultStreamPage
warning = [warning for warning in checks_result if warning.obj == DefaultStreamPage]
self.assertEqual(warning, [invalid_edit_handler])
@clear_edit_handler(ValidatedPage)
def test_custom_edit_handler_form_class(self):
"""