[Django]-Django 1.8 'default' option only executes external function once

4👍

Here you have django docs describing exactly what you want:
https://docs.djangoproject.com/en/1.8/howto/writing-migrations/#migrations-that-add-unique-fields

You will need two migration files.

  1. First one Adds fields, also change unique=True to null=True so django won’t try to use default value…
  2. Second migration populates the field.

So second migration should look like this:

def gen_uuid(apps, schema_editor):
    MyModel = apps.get_model('myapp', 'MyModel')
    for row in MyModel.objects.all():
        row.uuid = uuid.uuid4()
        row.save()


class Migration(migrations.Migration):

    dependencies = [
        ('myapp', '0004_add_uuid_field'),
    ]

    operations = [
        # omit reverse_code=... if you don't want the migration to be reversible.
        migrations.RunPython(gen_uuid, reverse_code=migrations.RunPython.noop),
    ]

1👍

In order to get a new value each time, you will need to set the default to a callable, otherwise as you have observed, uuid.uuid4 will be calculated once and then that single value will be used each time.

This other StackOverflow question and answer shows how to pass a callable as the default value.

EDIT: This answer only applies to versions of Django 1.7 and lower.

👤Aurora

Leave a comment