#14009 closed Bug (fixed)
custom formset validation documentation is incomplete
Reported by: | Owned by: | Tobias Kunze | |
---|---|---|---|
Component: | Documentation | Version: | dev |
Severity: | Normal | Keywords: | formset validation |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
The example for performing custom formset validation is incomplete. It does not take into account deleted forms, or empty forms for checking the unique titles constraint. It should read something along the lines of (changes highlighted by *>):
>>> class BaseArticleFormSet(BaseFormSet): ... def clean(self): ... """Checks that no two articles have the same title.""" ... if any(self.errors): ... # Don't bother validating the formset unless each form is valid on its own ... return ... titles = [] ... for i in range(0, self.total_form_count()): *> if self.can_delete and self._should_delete_form(form): *> continue ... form = self.forms[i] *> if 'title' in form.cleaned_data: ... title = form.cleaned_data['title'] ... if title in titles: ... raise forms.ValidationError, "Articles in a set must have distinct titles." ... titles.append(title)
Change History (10)
comment:1 by , 14 years ago
Has patch: | unset |
---|---|
Triage Stage: | Unreviewed → Accepted |
comment:2 by , 14 years ago
Severity: | → Normal |
---|---|
Type: | → Uncategorized |
Hi,
I think there's an "error" with the above suggestion too. self.errors will contain the errors of all forms (even if the form is marked for deletion). Supposing all NOT DELETED forms are valid, if some deleted form is in an invalid state, the code:
if any(self.errors): return
will make the "clean" method return too soon, avoiding the execution of the validation of the NOT DELETED forms.
AFAIK, formset.is_valid() can be True, even if formset.errors contains forms errors (from deleted forms).
In my case, I did something like:
(...) def clean(self) if self.is_valid(): try: # Get only the forms not marked for deletion cleaned_forms = list(set(self.forms) - set(self.deleted_forms)) except AttributError: # There're no forms marked for deletion (no self.deleted_forms) cleaned_forms = self.forms # validate logic with cleaned_forms (...)
If there's a better way to do this, let me know.
comment:3 by , 14 years ago
Type: | Uncategorized → Bug |
---|
comment:6 by , 6 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:7 by , 6 years ago
Has patch: | set |
---|
Accepted. For future reference, the file in question is
docs/topics/forms/formsets/
.