Skip to content

Instantly share code, notes, and snippets.

@dkirkham
Created July 17, 2021 00:31
Show Gist options
  • Save dkirkham/a1fc6d3a04754d5bb816cf97401fd357 to your computer and use it in GitHub Desktop.
Save dkirkham/a1fc6d3a04754d5bb816cf97401fd357 to your computer and use it in GitHub Desktop.
This validator checks the amount of text in a RichTextField, by stripping away basic formatting markup. It also incorporates an adjustment for markup that causes line breaks.
from wagtail.core.models import Page
from wagtail.core.fields import RichTextField
from proj.richtext_validator import RichTextLengthValidator
class AuthorPage(Page):
biography = RichTextField(
max_length=3600,
validators=[RichTextLengthValidator(3000, line_length=50)],
features=['bold', 'italic', 'link'],
blank=False,
null=True,
help_text="Full rich-text Biography"
)
from django.core.exceptions import ValidationError
from django.utils.deconstruct import deconstructible
from bs4 import BeautifulSoup
@deconstructible
class RichTextLengthValidator:
"""ImageField dimensions validator."""
def __init__(self, max_length, line_length, tag_weights=None):
"""
Constructor
Args:
max_length (int): maximum number of renders chars
line_length (int): nominal number of characters in a line
"""
self.max_length = max_length
self.line_length = line_length
if tag_weights:
self.tag_weights = tag_weights
else:
self.tag_weights = {
'li': line_length // 2,
'p': line_length // 2,
'br': line_length // 2,
}
def __call__(self, value):
bs_value = BeautifulSoup(value, 'html5lib')
length = 0
for string in bs_value.strings:
length += len(string)
tag_length = 0
for tag in bs_value.find_all():
if tag.name in self.tag_weights:
tag_length += self.tag_weights[tag.name]
total_weighted_length = length + tag_length
if total_weighted_length > self.max_length:
raise ValidationError(
"Ensure this richtext value is shorter than {} character equivalents (actual characters: {}, from formatting: {})".format(
self.max_length,
length,
tag_length
),
code='invalid',
params={'value': value}
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment