Reputation: 9484
Can I judge this is a bug? DateTimeField is inherited from DateField and it can be an optional
I have read: How to make Django's DateTimeField optional? How can I make my model fields optional in Django?
models.py
class Circuit(SoftDeletionModel):
...
created_datetime = models.DateTimeField(default=timezone.now)
updated_datetime = models.DateTimeField(auto_now=True)
expiry_datetime = models.DateTimeField(null=True, blank=True, default=None)
At terminal
$ python -B manage.py makemigrations --settings=config.settings.docker
apps.circuits is ready
apps.circuits_networkdevices is ready
apps.core is ready
apps.customers is ready
apps.networkdevices is ready
apps.networkscripts is ready
apps.portal is ready
apps.bod is ready
apps.scheduler is ready
You are trying to add a non-nullable field 'updated_datetime' to circuit 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 and django.utils.timezone modules are available, so you can do e.g. timezone.now()
>>> None
Migrations for 'circuits':
0022_auto_20161102_1714.py:
- Add field expiry_datetime to circuit
- Add field updated_datetime to circuit
migration_file.py
# -*- coding: utf-8 -*-
# Generated by Django 1.9.9 on 2016-11-02 10:14
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('circuits', '0021_auto_20161102_1653'),
]
operations = [
migrations.AddField(
model_name='circuit',
name='expiry_datetime',
field=models.DateTimeField(blank=True, default=None, null=True),
),
migrations.AddField(
model_name='circuit',
name='updated_datetime',
field=models.DateTimeField(auto_now=True, default=None),
preserve_default=False,
),
]
Error Django:
django.db.utils.IntegrityError: column "updated_datetime" contains null values
Error Postgres:
postgres_1 | ERROR: column "expiry_datetime" contains null values
postgres_1 | STATEMENT: ALTER TABLE "circuits_circuit" ADD COLUMN "expiry_datetime" timestamp with time zone NOT NULL
Spec:
In [2]: django.VERSION
Out[2]: (1, 9, 9, 'final', 0)
$ python --version
Python 3.5.1
> SELECT version();
+------------------------------------------------------------------------------------------+
| version |
|------------------------------------------------------------------------------------------|
| PostgreSQL 9.5.3 on x86_64-pc-linux-gnu, compiled by gcc (Debian 4.9.2-10) 4.9.2, 64-bit |
+------------------------------------------------------------------------------------------+
Upvotes: 4
Views: 15402
Reputation: 841
You have to delete all migrations and erase your database data too and do migrations again
excute commands:
python manage.py makemigrations
python manage.py migrate --fake
Upvotes: 0
Reputation: 5854
DateField.auto_now
Automatically set the field to now every time the object is saved.
DateField.auto_now_add
Automatically set the field to now when the object is first created.
You can use anyone:
created_date = models.DateTimeField(auto_now_add=True, null=True)
or
created_date = models.DateTimeField(null=True)
or
from django.utils import timezone
created_date = models.DateTimeField(default=timezone.now)
Upvotes: 1
Reputation: 10327
You cannot assign None
to updated_datetime
because you have not set null=True
in the model.
You have created a migration that tells django what to do if it encounters existing rows in the circuit
table when adding the field but that is not the same as being able to do it.
The default value asked for by the migration does not check that value is allowed to be used, it's trusting you to know what you are doing.
In your migration use datetime.now()
rather than None
.
Upvotes: 3