Adrian M Adrian M - 5 months ago 29
Python Question

In my models.py, one ForeignKey declaration does not require a default, but the other does? Why?

In attempting to run

manage.py makemigrations
, I received the following error:

You are trying to add a non-nullable field 'menu_category' to fooditem without
a default; we can't do that (the database needs something to populate existing
rows.


My code is as follows:

models.py



class FoodItem(models.model):
restaurant = models.ForeignKey('Restaurant', on_delete=models.CASCADE)
menu_category = models.ForeignKey('MenuCategory', on_delete=models.CASCADE)
...


The part that doesn't make sense is that no error occurs when I remove the menu_category line, despite the fact that the restaurant foreign key does not have a default either. Also, if I must specify a default value for a foreign key, what value would I even specify?

Answer

You're adding only a single new column called menu_category, right? The restaurant field does not give errors because it already exists.

Django gives you this error because you are adding a field that can't be null to a table that already exists without a default value. You either need to allow nulls (so the created column values can be empty in rows that already exist) or specify a default value to fill the column with.

Django should be asking you if you want to provide a "one-off" default value just for the migation. If you have some "default" menu category that the FoodItem objects can have, then specify its id when django prompts you for a value.

Example prmopt:

$ python manage.py makemigrations 
You are trying to add a non-nullable field 'menu_category' to fooditem without a default;
we can't do that (the database needs something to populate existing rows).
Please select a fix:
 1) Provide a one-off default now (will be set on all existing rows)
 2) Quit, and let me add a default in models.py
Select an option: 1
Please enter the default value now, as valid Python
The datetime module is available, so you can do e.g. datetime.date.today()
>>> 1
Migrations for 'my_app':
  0002_fooditem_menu_category.py:
    - Add field menu_category to fooditem