Sarit Sarit - 1 year ago 167
Python Question

Can not assign None to Django DateTimeField()

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?

class Circuit(SoftDeletionModel):
created_datetime = models.DateTimeField(
updated_datetime = models.DateTimeField(auto_now=True)
expiry_datetime = models.DateTimeField(null=True, blank=True, default=None)

At terminal

$ python -B 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
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.
>>> None
Migrations for 'circuits':
- Add field expiry_datetime to circuit
- Add field updated_datetime to circuit

# -*- 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 = [
field=models.DateTimeField(blank=True, default=None, null=True),
field=models.DateTimeField(auto_now=True, default=None),

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


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 |

Answer Source

You misunderstand what auto_now does

Automatically set the field to now every time the object is saved.

You'll still need to specify a valid default or allow for null values with null=True

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download