id summary reporter owner description type status component version severity resolution keywords cc stage has_patch needs_docs needs_tests needs_better_patch easy ui_ux
18441 A ModelForm with a blank=True, null=False ForeignKey doesn't validate jaylett nobody "For the following:
{{{
class Collection(models.Model):
created_by = models.ForeignKey(User, null=False, blank=True)
# and some other fields
}}}
(with a pre_save hook that populates `created_by` if it isn't already set), if on creation in the admin the HTML input for `created_by` is left empty (raw id) or unselected (non-raw id ie dropdown of all users), Django will attempt to set the field to `None`, which will result in a field validation failure:
{{{
File ""/home/james/projects/artfinder/ENV/lib/python2.6/site-packages/django/core/handlers/base.py"" in get_response
111. response = callback(request, *callback_args, **callback_kwargs)
File ""/home/james/projects/artfinder/ENV/lib/python2.6/site-packages/django/contrib/admin/options.py"" in wrapper
366. return self.admin_site.admin_view(view)(*args, **kwargs)
File ""/home/james/projects/artfinder/ENV/lib/python2.6/site-packages/django/utils/decorators.py"" in _wrapped_view
91. response = view_func(request, *args, **kwargs)
File ""/home/james/projects/artfinder/ENV/lib/python2.6/site-packages/django/views/decorators/cache.py"" in _wrapped_view_func
89. response = view_func(request, *args, **kwargs)
File ""/home/james/projects/artfinder/ENV/lib/python2.6/site-packages/django/contrib/admin/sites.py"" in inner
196. return view(request, *args, **kwargs)
File ""/home/james/projects/artfinder/ENV/lib/python2.6/site-packages/django/utils/decorators.py"" in _wrapper
25. return bound_func(*args, **kwargs)
File ""/home/james/projects/artfinder/ENV/lib/python2.6/site-packages/django/utils/decorators.py"" in _wrapped_view
91. response = view_func(request, *args, **kwargs)
File ""/home/james/projects/artfinder/ENV/lib/python2.6/site-packages/django/utils/decorators.py"" in bound_func
21. return func(self, *args2, **kwargs2)
File ""/home/james/projects/artfinder/ENV/lib/python2.6/site-packages/django/db/transaction.py"" in inner
209. return func(*args, **kwargs)
File ""/home/james/projects/artfinder/ENV/lib/python2.6/site-packages/django/contrib/admin/options.py"" in add_view
937. if form.is_valid():
File ""/home/james/projects/artfinder/ENV/lib/python2.6/site-packages/django/forms/forms.py"" in is_valid
124. return self.is_bound and not bool(self.errors)
File ""/home/james/projects/artfinder/ENV/lib/python2.6/site-packages/django/forms/forms.py"" in _get_errors
115. self.full_clean()
File ""/home/james/projects/artfinder/ENV/lib/python2.6/site-packages/django/forms/forms.py"" in full_clean
272. self._post_clean()
File ""/home/james/projects/artfinder/ENV/lib/python2.6/site-packages/django/forms/models.py"" in _post_clean
309. self.instance = construct_instance(self, self.instance, opts.fields, opts.exclude)
File ""/home/james/projects/artfinder/ENV/lib/python2.6/site-packages/django/forms/models.py"" in construct_instance
51. f.save_form_data(instance, cleaned_data[f.name])
File ""/home/james/projects/artfinder/ENV/lib/python2.6/site-packages/django/db/models/fields/__init__.py"" in save_form_data
454. setattr(instance, self.name, data)
File ""/home/james/projects/artfinder/ENV/lib/python2.6/site-packages/django/db/models/fields/related.py"" in __set__
362. (instance._meta.object_name, self.field.name))
Exception Type: ValueError at /admin/galleries/collection/add/
Exception Value: Cannot assign None: ""Collection.created_by"" does not allow null values.
}}}
I would expect this not to happen, allowing the presave hook to step in and do the right thing. If there's an obvious solution that I just haven't noticed, or no solution, then the rest of this can be skipped.
I believe that the following note in `BaseModelForm._get_validation_exclusions()` explains what's going on:
Note: don't exclude the field from
validation if the model field allows blanks. If it does, the blank
value may be included in a unique check, so cannot be excluded
from validation.
However I cannot find anything in the documentation that would suggest this behaviour. The current suggested solution, I think, would be to have the field explicitly listed in the `ModelForm` subclass **and** in `excludes` in that form. That would be something like:
{{{
class CollectionAdminForm(forms.ModelForm):
# need to exclude created_by, but explicitly list it as a field
created_by = # SOMETHING
class Meta:
model = Collection
exclude = ('created_by',)
}}}
however there's nothing in the documentation to suggest what the SOMETHING should be (ie what form field type should be used for `created_by`). If I try to use a `ModelChoiceField`, it doesn't populate it from the instance we're editing. Worse, because I'm linking to `User` I really want this to be a raw id field, and that seems to be utterly magical and doesn't have an actual form field type to represent it.
At this point I think I've convinced myself that Django cannot do what I want, ie there's no simple way of configuring the admin to allow a presave-populated `ForeignKey` to be settable on creation but to fall back to the presave population." Bug closed Forms 1.4 Normal duplicate Accepted 0 0 0 0 0 0