Since the using of an initial_data
fixture is deprecated, I'm trying to add initial data with a migration.
I created my models, and one of the models contains a permission code-named can_use_feature
.
When I run a makemigrations
, a 0001_initial.py
migration is created. The migrate
command creates the database, well populated and the permission from above is in the auth_permission
table.
Now I want to have a group with that permission by default in the database, so I create this migration as 0002_default_group.py
:
from __future__ import unicode_literals
from django.db import migrations
def create_default_group(apps, schema_editor):
GroupModel = apps.get_model('auth', 'group')
group = GroupModel(name='My Group')
group.save()
PermissionModel = apps.get_model('auth', 'permission')
permission = PermissionModel.objects.get(codename='can_use_feature')
group.permissions.add(permission)
class Migration(migrations.Migration):
dependencies = [
('myapp', '0001_initial'),
]
operations = [
migrations.RunPython(create_default_group),
]
Now something mysterious happens: When I delete the database again and execute the migrate
command, an DoesNotExist
error is raised, right at the permission = PermissionModel.objects.get(codename='can_use_feature')
line.
When I remove the 0002_default_group.py
, delete the database, execute migrate
, copy the 0002_default_group.py
back and run migrate
again, everything works fine and the group is created in the way I want it.
What must be changed in order to get the migration to work in only one step?
Permissions are created when the
post_migrate
signal fires. This signal is only fired if all migrations in the current run are completed. You cannot depend on the permissions existing within your migration.The signal receiver that creates the permissions checks for existing permissions, so you can simply create the permission yourself if it doesn't exist yet.
It would also be good to add a dependency on
('auth', '__latest__')
to ensure that the migrations for the Permission model have run and at least the table exists.