How to add unique field to existing Django model - a1k89/Blog GitHub Wiki
Prepare
- For example, you have existing Django
Usermodel - You want to add new unique field. For example,
referal_code - If simple add unique field and run
migratecommand - you got error (because some instances already exist)
Variants
- Add
Noneto field. Make migrations. Fill existing rows unique values and then add unique=True. Make migrations again - Via migrations.
Solution
I choose variant number 2.
- Add field to model
referal_code = models.CharField(editable=False,
default=referal_code_generator,
unique=True,
max_length=100)
- Run
makemigrations - Then, generate two empty migrations
makemigrations myapp --empty twice
- In a first migration change unique to null:
...
operations = [
migrations.AddField(
model_name='user',
name='referal_code',
field=models.CharField(default=apps.user.utils.referal_code_generator, editable=False,
max_length=100,
null=True),
),
]
- To the last migration please add (copy original code from first migration):
migrations.AlterField(
model_name='user',
name='referal_code',
field=models.CharField(default=apps.user.utils.referal_code_generator, editable=False,
max_length=100,
unique=True),
),
- And finally, change second migration to:
def gen_referal_code(apps, schema_editor):
User = apps.get_model('user', 'User')
for row in User.objects.all():
row.referal_code = utils.referal_code_generator()
row.save(update_fields=['referal_code'])
class Migration(migrations.Migration):
....
operations = [
migrations.RunPython(gen_referal_code, reverse_code=migrations.RunPython.noop)
]
- Run
migrate.
After that our actions will be:
- The first migration add
nullvalues toreferal_code - The second migration fill existing rows unique values
- The last migration add
unique=Trueto our field.
Thanks for reading