Opened 14 years ago
Closed 11 years ago
#15995 closed Bug (duplicate)
Problems in ModelForm._post_clean
Reported by: | Florian Apolloner | Owned by: | nobody |
---|---|---|---|
Component: | Forms | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Hi,
I have a model with the following field:
author = models.ForeignKey(User, on_delete=models.PROTECT)
The related modelform sets this field to required = False
This field should obviously pass form validation in the admin since required will be False! But then in _post_clean of the modelform it tries to construct the instance: http://code.djangoproject.com/browser/django/trunk/django/forms/models.py#L308
which immediately fails cause author can't be None: http://dpaste.com/540716/
Oddly enough, the code later on collects the fields for model validation: exclude = self._get_validation_exclusions(). This code would add author to the ignore list: http://code.djangoproject.com/browser/django/trunk/django/forms/models.py#L288
So model validation would be happyily exclude my field from validation, but it already fails in construct_instance. I think _post_clean should use the calculated exclude list instead of opts.exclude for the construct_instance call
Attachments (2)
Change History (8)
by , 14 years ago
by , 14 years ago
comment:1 by , 14 years ago
comment:2 by , 14 years ago
Triage Stage: | Unreviewed → Accepted |
---|
The idea makes sense. It would make the form validation slightly more tolerant, but that's not significantly backwards incompatible.
comment:3 by , 14 years ago
Hmm, my suggested solution won't work out. It works in my case, but if someone supplies real data it won't get set :( On the other way I fail to find an easy way around it *gg*
comment:4 by , 14 years ago
UI/UX: | unset |
---|
Personally I think that using "construct_instance" function inside form's _post_clean method is not good idea.
Maybe it should me method? - If it would be a method it will be easy to change the way of instance construction.
Everybody who is unhappy with it will have opportunity to change it easily.
Here's my idea (should be part of django.forms.models.BaseModelForm class)
{{
def _construct_instance(self):
opts = self._meta
return django.forms.models.construct_instance(self, self.instance, fields=opts.fields, exclude=opts.exclude)
def _post_clean(self):
self.instance = self._construct_instance()
# ... the rest of _post_clean method
}}
Attached models.py and admin.py. My endgoal was to be able to set the author later on, without making the field nullable, If pass the excludes from _get_validation_excludes into construct_instance everything works…