Django Migrations and UUID Fields
Recently I wanted to add a UUID field to an existing model called Institution, this model represents the Institutions that support the Open Library Humanities and the UUID field would represent a referral code. I added the following line to models.py and ran makemigrations.
referral_code = models.UUIDField(default=uuid.uuid4)
Unfortunately, this works perfectly for new instances of Institution, it will generate the same UUID for all of the existing objects. To get around this we need to alter the migration that has been generated.
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2018-02-26 19:29
from __future__ import unicode_literals
from django.db import migrations, models
import uuid
def create_uuid(apps, schema_editor):
Institution = apps.get_model('consortial_billing', 'Institution')
for inst in Institution.objects.all():
inst.referral_code = uuid.uuid4()
inst.save()
class Migration(migrations.Migration):
dependencies = [
('consortial_billing', '0031_supportlevel_description'),
]
operations = [
migrations.AddField(
model_name='institution',
name='referral_code',
field=models.UUIDField(blank=True, null=True),
),
migrations.RunPython(create_uuid),
migrations.AlterField(
model_name='institution',
name='referral_code',
field=models.UUIDField(default=uuid.uuid4, unique=True)
)
]
I’ve edited the original AddField statement so it makes a blank=True, null=True version of our field, then I’ve added a RunPython command that gets all off the existing Institution objects and assigns them a uuid4 before finally setting a default and making it unique.