Django models: default datetime is not translated into SQL CURRENT_TIMESTAMP

Viewed 943

I am using Django models to create a PostgreSQL-DB. I have a DateTimeField where I would like to set the current timestamp as default value. I am aware of multiple sources suggesting how to do this. However, when I inspect my DB outside of Django, the default timestamp doesn't show up.

Approaches I have tried:

1.

created_at = models.DateTimeField(auto_now_add=True)
from django.db.models.functions import Now
...
created_at = models.DateTimeField(default=Now())
from django.utils.timezone import now
...
created_at = models.DateTimeField(default=now)

What I would expect is for the PostgreSQL database to show: TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP

What It shows is timestamp with time zone not null but no default value. Any ideas on how to do that would be greatly appreciated.

1 Answers

However, when I inspect my DB outside of Django, the default timestamp doesn't show up.

That is correct, Django itself manages the default values. Not the database, Django also manages the ON DELETE trigger, not the database. This gives more flexibility. For example you can pass a callable to the default like you did with default=now. This callable can perform sophisticated actions to determine the default value like making extra queries, API calls, file I/O, etc. This is not possible with a default at the database side.

You can make a data migration file and manually alter the table. You can initialize a data migration with:

python manage.py makemigrations --empty app_name

next you can alter the file it has generated and specify a default with:

# Generated by Django 3.1 on 2020-12-16 17:14
from django.db import migrations

class Migration(migrations.Migration):

    dependencies = [
        ('app_name', 'migration_name'),
    ]

    operations = [
        migrations.RunSQL(
            'ALTER TABLE table_name ALTER COLUMN created_at SET DEFAULT CURRENT_TIMESTAMP';
        )
    ]

The advantage of doing this is that Django manages the migrations, and it will thus migrate the databases that have not been migrated and thus add a default value.

Related