The trick here is knowing that Token
uses a custom save()
method to generate a unique token.key
but that custom save()
methods are not run inside migrations. So the first token will have a blank key and the second will fail with an IntegrityError
because they key is also blank and not unique.
Instead, copy the generate_key()
code into your migration like this:
# Generated with `manage.py makemigrations --empty YOUR-APP`.
import binascii
import os
from django.db import migrations
# Copied from rest_framework/authtoken/models.py.
def generate_key():
return binascii.hexlify(os.urandom(20)).decode()
def create_tokens(apps, schema_editor):
User = apps.get_model('auth', 'User')
Token = apps.get_model('authtoken', 'Token')
for user in User.objects.filter(auth_token__isnull=True):
token, _ = Token.objects.get_or_create(user=user, key=generate_key())
class Migration(migrations.Migration):
dependencies = [
('YOUR-APP', 'YOUR-PREVIOUS-MIGRATION'),
]
operations = [
migrations.RunPython(create_tokens),
]
You should avoid importing the rest_framework
code directly into a migration or one day your migrations will fail to run because you decided to remove rest_framework or the library's interface changed. Migrations need to be frozen in time.