Hannu Huhtanen
Hannu Huhtanen

Reputation: 35

How to reference generated permissions in Django 1.7 migrations

I'm trying to create a auth.Group with permissions automaticly with migrations. My problem is that when I run migrate on empty database the migration that tries to attach permission to the group can't find the permission. If I target an earlier migration so that migrate exits without an error the permissions appear into the database and after that the migration code can find the permission. So what can I do so that the migration can reference a permission which is created in an earlier migration when the migrations are run back to back?

def load_data(apps, schema_editor):
    Permission  = apps.get_model('auth', 'Permission')
    Group       = apps.get_model('auth', 'Group')

    can_add = Permission.objects.get(codename='add_game')
    developers = Group.objects.create(name='Developer')

    developers.permissions.add(can_add)
    developers.save()


class Migration(migrations.Migration):

    dependencies = [
        ('myApp', '0004_game'),
    ]

    operations = [
        migrations.RunPython(load_data),
    ]

The game model is created in an earlier migration. This code causes always an error stating that Permission matching query does not exist when I run it with other migrations on an empty database. I'm using python 3.4 with django 1.7.2

Upvotes: 3

Views: 639

Answers (1)

Oh. 4 years later... To create permissions Django uses post_migrate signal.

Therefore, when running all migrations at a time, permissions do not yet exist.

Therefore, you can take out your function, for example, in the management command.

However, you can still do it like this:

from django.contrib.auth.management import create_permissions


APPS = [
    ...your app labels
]


def create_applications_permissions():
    for app in APPS:
        app_config = django_apps.get_app_config(app)
        create_permissions(app_config)


def load_data(apps, schema_editor):
    create_applications_permissions()
    Permission  = apps.get_model('auth', 'Permission')
    Group       = apps.get_model('auth', 'Group')

    can_add = Permission.objects.get(codename='add_game')
    developers = Group.objects.create(name='Developer')

    developers.permissions.add(can_add)
    developers.save()


class Migration(migrations.Migration):

    dependencies = [
        ('myApp', '0004_game'),
    ]

    operations = [
        migrations.RunPython(load_data),
    ]

And to create permissions do not use apps passed to the migration. Will not pass the check in create_permissions:

if not app_config.models_module:
    return

But you have to be careful.

I hope someone will be useful.

Upvotes: 3

Related Questions