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.

Written by

Pub Tech developer for Birkbeck CTP

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store