Is it possible to add to existing model auto_now
and auto_now_add
DateTime fields?
class ExistingModel(models.Model):
# ... model stuff
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
We can't add this fields without default
, but adding the default
value gives an error:
./manage.py makemigrations
returns:
(fields.E160) The options auto_now, auto_now_add, and default are mutually exclusive. Only one of these options may be present.
You can make that happen in 2 separate migrations.
First, add a default=<some datetime>
to both of your new datetime fields and create that migration.
Then remove the default
and add auto_now
parameters and create the 2nd migration.
Update -
It's possible to have both of these combined into a single migration (preserving the order) by generating the 2 migrations and simply cut-paste the 2nd migrations' content into the first (and then delete the 2nd migration file).
example migration file 00XY_existing_model_add_timestamps
-
from django.db import migrations, models
from django.utils import timezone
def update_datetimes(app, schema_editor):
print() # new line
ExistingModel = app.get_model("my_app", "ExistingModel")
for instance in ExistingModel.objects.all():
instance.created_at = # calculate & set something based on the instance attributes
instance.updated_at = # calculate & set something based on the instance attributes
print("\tUpdated created_at & updated_at for all rows in ExistingModel")
class Migration(migrations.Migration):
dependencies = [("my_app", "00XX_previous_migration")]
operations = [
migrations.AddField(
model_name="ExistingModel",
name="created_at", # name of your new field
field=models.DateTimeField(default=timezone.now), # replace timezone.now with any datetime value you want
preserve_default=False,
),
migrations.AddField(
model_name="ExistingModel",
name="updated_at", # name of your new field
field=models.DateTimeField(default=timezone.now), # replace timezone.now with any datetime value you want
preserve_default=False,
),
# uncomment the below migration operation if you want to dynamically set old datetimes
# migrations.RunPython(
# update_datetimes, reverse_code=migrations.RunPython.noop
# ),
migrations.AlterField(
model_name="ExistingModel",
name="created_at",
field=models.DateTimeField(auto_now_add=True),
),
migrations.AlterField(
model_name="ExistingModel",
name="updated_at",
field=models.DateTimeField(auto_now=True),
),
]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With