kopia lustrzana https://github.com/wagtail/wagtail
Rework deferring validation on StreamField
Overwriting a block's `required` option is not safe, as a block object is part of a class-level definition and is thus shared by all block instances, not just the one currently being validated. Instead, introduce a flag to Block.clean to skip 'required' validation.pull/12946/head
rodzic
c38db51559
commit
6d01356ec6
wagtail/blocks
|
@ -756,10 +756,22 @@ class BlockField(forms.Field):
|
|||
super().__init__(**kwargs)
|
||||
|
||||
def clean(self, value):
|
||||
# Pass required flag to the top-level block, so that dynamically setting it on the
|
||||
# field (e.g. by defer_required_fields) is respected by the block.
|
||||
self.block.set_meta_options({"required": self.required})
|
||||
return self.block.clean(value)
|
||||
from wagtail.blocks.stream_block import StreamBlock
|
||||
|
||||
if isinstance(self.block, StreamBlock):
|
||||
# StreamBlock is the only block type that is formally-supported as the top level block
|
||||
# of a BlockField, but it's possible that other block types could be used, so check
|
||||
# this explicitly.
|
||||
# self.block has a `required` attribute that is consistent with the StreamField's `blank`
|
||||
# attribute and thus the `required` attribute of BlockField - but if the latter has been
|
||||
# assigned dynamically (e.g. by defer_required_fields) we want this to take precedence.
|
||||
# We do this through the `ignore_required_constraints` flag recognised by
|
||||
# StreamBlock.clean.
|
||||
return self.block.clean(
|
||||
value, ignore_required_constraints=not self.required
|
||||
)
|
||||
else:
|
||||
return self.block.clean(value)
|
||||
|
||||
def has_changed(self, initial_value, data_value):
|
||||
return self.block.get_prep_value(initial_value) != self.block.get_prep_value(
|
||||
|
|
|
@ -160,7 +160,7 @@ class BaseStreamBlock(Block):
|
|||
def required(self):
|
||||
return self.meta.required
|
||||
|
||||
def clean(self, value):
|
||||
def clean(self, value, ignore_required_constraints=False):
|
||||
cleaned_data = []
|
||||
errors = {}
|
||||
non_block_errors = ErrorList()
|
||||
|
@ -179,7 +179,7 @@ class BaseStreamBlock(Block):
|
|||
% {"min_num": self.meta.min_num}
|
||||
)
|
||||
)
|
||||
elif self.required and len(value) == 0:
|
||||
elif self.required and not ignore_required_constraints and len(value) == 0:
|
||||
non_block_errors.append(ValidationError(_("This field is required.")))
|
||||
|
||||
if self.meta.max_num is not None and self.meta.max_num < len(value):
|
||||
|
|
Ładowanie…
Reference in New Issue