ForeignKey Fields null=True does not imply blank=True

333 views
Skip to first unread message

khoobks

unread,
Aug 26, 2015, 5:59:35 AM8/26/15
to Django users
Hi All,

I just discovered some interesting behaviour in Django 1.8.4 and was wondering if this was an unexpected side effect or specifically designed behaviour.


class UserProfile(models.Model):
    # Notice that I do not say that blank=True
    my_other_model = models.ForeignKey('my_app.OtherModel', null=True)


I would have expected that since it doesn't make sense for a ForeignKey to have a 'blank' value, by saying that null=True it would implicitly mean that blank=True.
However to my surprise this is not the case.

This came to my attention when using ModelForms. I found out that it is possible to assign the foreign key in the Form to a non null value, but it was not possible to reassign it back to the 'blank/null' value.

The reason is that in django/forms/models.py there is a function called '_get_validation_exclusions'. This function does a check on line 376

if not f.blank and not form_field.required and field_value in form_field.empty_values

which specifically looks at the 'blank' attribute of the model field. If this is False, then you will go into the if block and your field will be added to the exclusion list and therefore never saved.

To me, this seems like an unnecessary trap for users of the Django Framework. However there may be a design decision here and I'd love to be educated on why there would be a situation where it makes sense for null=True and blank=False.

Regards
Ben

Florian Schweikert

unread,
Aug 26, 2015, 7:43:16 AM8/26/15
to django...@googlegroups.com
On 26/08/15 11:59, khoobks wrote:
> I just discovered some interesting behaviour in Django 1.8.4 and was
> wondering if this was an unexpected side effect or specifically designed
> behaviour.

That behaviour is intended and documented[0].

blank and null working on completely different levels.
blank is only for validation in the django code.
null affects the database field.

It's useful if you like to force the user to input something in a field,
but at the same time you have to initialise a model with null at some
other place in your code.
e.g you are importing email addresses, but don't have names in your
current data. You can now easily force the user to set his/her name when
changing settings, without overwriting fields in a form.

regards,
Florian

[0] https://docs.djangoproject.com/en/1.8/ref/models/fields/#null

signature.asc

khoobks

unread,
Aug 26, 2015, 8:18:48 AM8/26/15
to Django users, kel...@ist-total.org
That makes sense however I would have expected the ModelForm to give an error indicating that the foreign key is blank (when it should not be) instead of adding it to the exclusion list meaning that it never gets updated when you call save.

khoobks

unread,
Aug 26, 2015, 8:43:16 AM8/26/15
to Django users, kel...@ist-total.org
It just occurred to me where I went wrong. 

I have a line that makes the form field non-required which means the form won't flag the validation error. 

Thanks Florian

Mark Caglienzi

unread,
Aug 26, 2015, 8:50:07 AM8/26/15
to django...@googlegroups.com
On 26 Aug 2:59, khoobks wrote:
> Hi All,

Hello!

> To me, this seems like an unnecessary trap for users of the Django
> Framework. However there may be a design decision here and I'd love to be
> educated on why there would be a situation where it makes sense for
> null=True and blank=False.

Well, maybe it's useful if you want to be able to programmatically
(a.k.a. in the backend, or with a management command, maybe even called
by a cronjob) create some objects with that FK set to NULL (probably
because in your case you cannot possibly know how to set it), but you
want to force the user to specify a value when updating them (so in that
moment the blank=True will enforce this behaviour).

> Regards
> Ben

Regards,
Mark

--
. ''`. | GPG Public Key : 0xCD542422 - Download it from http://is.gd/fOa7Vm
: :' : | GPG Fingerprint : 0823 A40D F31B 67A8 5621 AD32 E293 A2EB CD54 2422
`. `'` | Powered by Debian GNU/Linux, http://www.debian.org
`- | Try not. Do, or do not. There is no try. - Master Yoda, TESB.
Reply all
Reply to author
Forward
0 new messages