From 3fa5eb125cac752ce46362bad31484c874498b43 Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Fri, 8 Jul 2022 18:40:07 +0100 Subject: [PATCH] Implement max_length validation on RichTextBlock --- docs/reference/streamfield/blocks.md | 1 + wagtail/blocks/field_block.py | 11 ++++++++++- wagtail/tests/test_blocks.py | 14 ++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/docs/reference/streamfield/blocks.md b/docs/reference/streamfield/blocks.md index 011df6c111..6fe66cac5a 100644 --- a/docs/reference/streamfield/blocks.md +++ b/docs/reference/streamfield/blocks.md @@ -205,6 +205,7 @@ All block definitions accept the following optional keyword arguments: :param editor: The rich text editor to be used (see :ref:`WAGTAILADMIN_RICH_TEXT_EDITORS`). :param features: Specifies the set of features allowed (see :ref:`rich_text_features`). :param required: If true (the default), the field cannot be left blank. + :param max_length: The maximum allowed length of the field. Only text is counted; rich text formatting and embedded content does not count towards the limit. :param help_text: Help text to display alongside the field. :param validators: A list of validation functions for the field (see `Django Validators `__). :param form_classname: A value to add to the form field's ``class`` attribute when rendered on the page editing form. diff --git a/wagtail/blocks/field_block.py b/wagtail/blocks/field_block.py index ee9e7b4e90..702235aa1b 100644 --- a/wagtail/blocks/field_block.py +++ b/wagtail/blocks/field_block.py @@ -13,7 +13,11 @@ from django.utils.translation import gettext as _ from wagtail.admin.staticfiles import versioned_static from wagtail.coreutils import camelcase_to_underscore, resolve_model_string -from wagtail.rich_text import RichText, get_text_for_indexing +from wagtail.rich_text import ( + RichText, + RichTextMaxLengthValidator, + get_text_for_indexing, +) from wagtail.telepath import Adapter, register from .base import Block @@ -642,9 +646,14 @@ class RichTextBlock(FieldBlock): help_text=None, editor="default", features=None, + max_length=None, validators=(), **kwargs, ): + if max_length is not None: + validators = list(validators) + [ + RichTextMaxLengthValidator(max_length), + ] self.field_options = { "required": required, "help_text": help_text, diff --git a/wagtail/tests/test_blocks.py b/wagtail/tests/test_blocks.py index 67ecf00b15..f869bc4a87 100644 --- a/wagtail/tests/test_blocks.py +++ b/wagtail/tests/test_blocks.py @@ -629,6 +629,20 @@ class TestRichTextBlock(TestCase): with self.assertRaises(ValidationError): block.clean(RichText("

bar

")) + def test_validate_max_length(self): + block = blocks.RichTextBlock(max_length=20) + + block.clean(RichText("

short

")) + + with self.assertRaises(ValidationError): + block.clean(RichText("

this exceeds the 20 character limit

")) + + block.clean( + RichText( + '

also short

' + ) + ) + def test_get_searchable_content(self): block = blocks.RichTextBlock() value = RichText(