Abhishek VD
Abhishek VD

Reputation: 65

Python django non-nullable field

Here is my models.py

class Product(models.Model):
    product_id = models.AutoField
    product_name = models.CharField(max_length=50)
    category = models.CharField(max_length = 50, default="")
    price = models.ImageField(default=0)
    sub_category = models.CharField(max_length = 50,default="")
    desc = models.CharField(max_length=300)
    pub_date = models.DateField()
    image = models.ImageField(upload_to="shop/images", default="")

And I'm getting the line below. I don't know whether it is warning or error: You are trying to add a non-nullable field 'pub_date' to the product without a default; we can't do that (the database needs something to populate existing rows).

What does it mean actually ??

Upvotes: 1

Views: 1950

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477607

You already constructed migrations where you create the table for the Product table. It is thus possible that there are already records for that table.

Now you are adding a new column, this thus means you need to fill the column for the existing records. You did not specify a default=… parameter [Django-doc], hence Django can not use this as a value.

For a field with null=True [Django-doc] without a default value, by default it will use None/NULL as value, but here your pub_date is not a nullable field.

This thus means that Django does not know what to do here. Normally Django will propose two solutions:

 1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
 2) Quit, and let me add a default in models.py

First option

You thus select the first option by writing 1 (and Enter), then you can enter an expression that specifies what to use as default, for example timezone.now as the default for the existing records, not the new records:

Please enter the default value now, as valid Python
The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now
Type 'exit' to exit this prompt
>>> timezone.now  # Enter

Second option

If you select 2 (and Enter), Django will stop creating the migration file, and give you the opportunity to specify a default yourself in the models.py: this will then be used for all existing and new records. For example:

from django.utils import timezone

class Product(models.Model):
    # …
    pub_date = models.DateField(default=timezone.now)
    # …

You can also use auto_now_add=True [Django-doc] to automatically use the current date as value, and make the field non-editable:

class Product(models.Model):
    # …
    pub_date = models.DateField(auto_now_add=True)
    # …

Upvotes: 4

Related Questions