Migrate `DateTimeField` to `DateField` in Django

I got objects that have an attribute that is a DateTimeField now I want to change this to a DateField.

But I already have data in my database so just doing this migration:

    migrations.AlterField(
        model_name='assignedtip',
        name='date',
        field=models.DateField(),
    ),

will not work, as the table is broken afterwards.

How can I make sure, that when executing this migration with makemigration the DateTimeField values are first converted to DateFields?

>Solution :

I think it might be better to do this in four steps:

  1. first add a field assignedtip_date that contains NULL for a start;
  2. then run a data migration that populates the field with the truncated part of the assignedtip;
  3. then remove the assginedtip field; and
  4. finally rename the assginedtip_date field to assignedtip.

The migration thus will look like:

# app_name/migrations/0123_some_name.py

from django.db import migrations, models
from django.db.models.functions import TruncDate


def migrate_date(apps, schema_editor):
    MyModel = apps.get_model("app_name", "MyModel")
    MyModel.objects.update(assignedtip_date=TruncDate('assignedtip'))


class Migration(migrations.Migration):
    dependencies = [("migrations", "0001_initial")]

    operations = [
        migrations.AddField(
            "MyModel", "assignedtip_date", models.DateField(null=True)
        ),
        migrations.RunPython(migrate_date),
        migrations.RemoveField("MyModel", "assignedtip"),
        migrations.RenameField("MyModel", "assignedtip_date", "assignedtip"),
    ]

Leave a Reply