Defer validation of required text fields until publish time#12923
Defer validation of required text fields until publish time#12923gasman merged 20 commits intowagtail:mainfrom
Conversation
Manage this branch in SquashTest this branch here: https://featurevalidate-on-publish-3-97bsx.squash.io |
ce5b027 to
1fda901
Compare
laymonage
left a comment
There was a problem hiding this comment.
I tested it and it works very well! Just a few non-blocking comments, otherwise it looks good to me, thanks!
| def get_cell_context_data(self, instance, parent_context): | ||
| context = super().get_cell_context_data(instance, parent_context) | ||
| if not str(context["value"]).strip(): | ||
| context["value"] = "(blank)" |
There was a problem hiding this comment.
Happy to go with this for now, but I wonder if the columns should support something similar to ModelAdmin's empty_value_display more generally?
There was a problem hiding this comment.
Seems like a good idea! Added in 453ef62 (and made translatable along the way).
| # If required_on_save is not explicitly set, treat it as false unless: | ||
| # - it corresponds to a model field with required_on_save=True (such as page title) | ||
| # - it corresponds to a non-null, non-text-typed model field (in which case a blank value | ||
| # is not valid at the database level) |
| @property | ||
| def action_name(self): | ||
| return self.action_name_and_method[0] | ||
|
|
||
| @property | ||
| def action_method(self): | ||
| return self.action_name_and_method[1] |
There was a problem hiding this comment.
Thank you, I've been thinking of doing some kind of mapping between the action name and method, but I think this works just as well!
| if result.strip() == "": | ||
| result = f"{obj.__class__.__name__} object ({obj.pk})" |
There was a problem hiding this comment.
Should this (and the other fallbacks, i.e. in audit log and table column) be translatable? Django's isn't, but we might want to do so as it's user-facing.
| if self.form.is_valid(): | ||
| return self.form_valid(self.form) | ||
| else: | ||
| self.form.restore_required_fields() |
| If ``clean=False`` is passed, the page is saved without validation. This is appropriate for updates that only | ||
| change metadata such as `latest_revision` while keeping content and page location unchanged. | ||
|
|
||
| By default, pages are validated using ``full_clean()`` before attempting to | ||
| save changes to the database, which helps to preserve validity when restoring | ||
| pages from historic revisions (which might not necessarily reflect the current | ||
| model state). This validation step can be bypassed by calling the method with | ||
| ``clean=False``. | ||
| If ``clean=True`` is passed (the default), and the page has ``live=True`` set, the page is validated using | ||
| :meth:`~django.db.models.Model.full_clean` before saving. | ||
|
|
||
| If ``clean=True`` is passed, and the page has `live=False` set, only the title and slug fields are validated. |
There was a problem hiding this comment.
Not sure if we ever did it inside docstrings, but does the change warrant a versionchanged admonition? If we don't want it in the docstring, maybe we can add it below the .. automethod:: save in the Markdown file.
There was a problem hiding this comment.
Yep, that can't hurt... now added in e3f674a.
laymonage
left a comment
There was a problem hiding this comment.
One non-blocking comment about empty_value_display, but otherwise this looks good to me. Thanks!
| value = unlocalize(value) | ||
| context["value"] = value | ||
|
|
||
| if not str(value).strip(): |
There was a problem hiding this comment.
Just want to note that Django's logic is as follows:
If the value of a field is
None, an empty string, or an iterable without elements, Django will display - (a dash). You can override this withAdminSite.empty_value_display:
I think taking None into consideration so that users can override empty_value_display to customise its display would be a common use case. However, we might want to change the default value to a dash like Django, as otherwise it would display as an empty string.
It's not in the scope of this PR though, but I thought I'd raise this since we're just about to add the support. Also happy to do this in a separate PR.
There was a problem hiding this comment.
Yep, since this is a potential change of behaviour on existing listings, i think that's best left for a separate PR.
… from_date field The fix to EventPageForm.clean addresses a logic bug that existed before the change to validation - if `date_from` was left blank, it would be omitted from `cleaned_data` and so retrieving it would raise an uncaught KeyError.
It is clear from the test models and bakerydemo that title is frequently declared with a plain FieldPanel rather than TitleFieldPanel, so we should not rely on the presence of TitleFieldPanel or an explicit required_on_save flag on the FieldPanel to enforce form-level validation on the title.
… non-text-type model fields
…r scheduling As per wagtail/rfcs#104 (comment) - unless clean=False is explicitly passed, validation should be applied, including on fields that would accept nulls at the database level.
…ests for creating/editing invalid draft snippets
…wing form after an error
…lank This surfaces an issue with SearchPromotion having a broken string representation when the query string is None, so fix that too
e3f674a to
0df0a20
Compare
Implements RFC 104 for required fields on page and snippet models.