152

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?

Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
user1
  • 2,159
  • 3
  • 19
  • 19

3 Answers3

271

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)
akki
  • 2,021
  • 1
  • 24
  • 35
Abid A
  • 7,588
  • 4
  • 32
  • 32
  • 12
    Are both needed? What would be the downsides of just using null=True ? – Ward Jan 21 '16 at 08:15
  • 16
    @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 (''). – fang_dejavu Jun 20 '16 at 18:32
  • 8
    @Ward, both are not needed. It is sufficient to just use `null=True`. – Clay Risser May 20 '17 at 22:27
  • 30
    `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. – cezar Aug 23 '18 at 10:31
  • 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. – JFlo Oct 09 '18 at 13:59
  • In Django Rest Framework, it seems you also have to specify required=False in the serializer: https://github.com/encode/django-rest-framework/issues/627. Something like subject=SubjectSerializer(required=False). – Little Brain May 26 '19 at 14:55
  • `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" – Swift Sep 30 '19 at 14:24
  • Thanks for the tip. For me (Django 3.2.7) it was asked to me to add : missing 1 required positional argument: 'on_delete' – Abpostman1 Mar 22 '22 at 12:32
10

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)
Muhammad Zubair
  • 466
  • 5
  • 17
0

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
)
Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129