How to make the foreign key field optional in Django model?
Asked Answered
R

3

160

I have the following code:

subject = models.ForeignKey(subjects)
location = models.ForeignKey(location)
publisher = models.ForeignKey(publisher)

It is possible that I won't have all three values of the books. Sometimes I might not know the subject or location, or publisher. In this case I want to leave them empty.

But if values exist then I need a select box from which to select them. Is this possible?

Randi answered 8/7, 2011 at 4:28 Comment(0)
N
282

Sure, just add blank=True, null=True for each field that you want to remain optional like

subject = models.ForeignKey(subjects, blank=True, null=True)
Noach answered 8/7, 2011 at 4:58 Comment(8)
Are both needed? What would be the downsides of just using null=True ?Terisateriyaki
@WardC The combo of the two is so frequent because typically if you're going to allow a field to be blank in your form, you're going to also need your database to allow NULL values for that field. The exception is CharFields and TextFields, which in Django are never saved as NULL. Blank values are stored in the DB as an empty string ('').Meridional
@Ward, both are not needed. It is sufficient to just use null=True.Foliar
blank=True is important for form validation. It will allow an empty string as user input in this field. null=True will allow NULL value in the database column.Holinshed
Is something else required if you originally didn't have blank=True, null=True but do now with the migrations applied? I have this situation and while the schema looks good, the admin form won't allow a blank. Other FKs that allowed blanks originally work though and I don't see the difference.Fructify
In Django Rest Framework, it seems you also have to specify required=False in the serializer: github.com/encode/django-rest-framework/issues/627. Something like subject=SubjectSerializer(required=False).Deerskin
blank is for "blank input from form data e.g. the user could enter nothing in this field" null is for "allow to be stored as null (nothing) in the database"Aspirator
Thanks for the tip. For me (Django 3.2.7) it was asked to me to add : missing 1 required positional argument: 'on_delete'Cain
P
12

In order to accomplish this, the on_delete argument is necessary along with blank=True and null=True, and it would be better if you do it this way.

subject = models.ForeignKey(subjects, on_delete=models.SET_NULL, blank=True, null=True)
Palla answered 8/5, 2021 at 8:38 Comment(0)
A
2

You need to set blank=True and null=True to models.ForeignKey() to make the foreign key field optional and on_delete also needs to be set to it as shown below:

my_field = models.ForeignKey(
    Parent_model, 
    blank=True, # Here
    null=True, # Here
    on_delete=models.CASCADE # Here
)

*Be careful, only setting either blank=True or null=True to models.ForeignKey() is not enough to make the foreign key field optional so you need to set both of them to it.

In addition, if you want to achieve what you want with models.OneToOneField(), you need to set the same arguments as shown below:

my_field = models.OneToOneField(
    Parent_model, 
    blank=True, # Here
    null=True, # Here
    on_delete=models.CASCADE # Here
)
Ancipital answered 11/5, 2023 at 7:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.