[Django]-Django β€” new field: How to set default callable for existing objects

9πŸ‘

βœ…

you can do it by manual edit migration,

  1. do makemigrations with null
  2. do makemigrations with not null
  3. Edit first make migration by add datamigration with update and move operations from second migrate file
  4. remove the second migrations file,

for example:

from django.db import migrations, models
from django.db.models import F

def set_price_total(apps, schema_editor):
    # Change the myapp on your
    Model = apps.get_model('myapp', 'Model')
    Model.objects.update(price_total=F('price'))


class Migration(migrations.Migration):

    dependencies = [
        ('myapp', '0001_initial'),
    ]

    operations = [
        migrations.AddField(
            model_name='model',
            name='price_total',
            field=models.DecimalField(
                decimal_places=2, max_digits=10, null=True),
        ),

        migrations.RunPython(set_price_total),

        migrations.AlterField(
            model_name='model',
            name='price_total',
            field=models.DecimalField(
                decimal_places=2, default=1, max_digits=10),
            preserve_default=False,
        ),
    ]

3πŸ‘

You are on track to do it properly.

Just make sure step 3 in done in a datamigration (certainly not through django shell).

This way you won’t forget to run it on production.

I’m pretty sure you can’t do both add the column and setting the value to be the same as another column.

To convince yourself, you can search for vanilla SQL implementation like https://stackoverflow.com/a/13250005/1435156

Leave a comment