Adding django admin permissions in a migration: Permission matching query does not exist

点点圈 提交于 2019-11-28 09:56:16

In django 1.10 the following code could be used:

from django.contrib.auth.management import create_permissions

def migrate_permissions(apps, schema_editor):
    for app_config in apps.get_app_configs():
        app_config.models_module = True
        create_permissions(app_config, apps=apps, verbosity=0)
        app_config.models_module = None

Django <= 1.9

see another answer for Django 1.10+

It's enough to call create_permissions:

from django.contrib.auth.management import create_permissions

apps.models_module = True
create_permissions(apps, verbosity=0)
apps.models_module = None

The whole migration being something like this

# coding:utf-8
from django.db import migrations
from django.contrib.auth.models import Permission, Group
from django.contrib.auth.management import create_permissions
from django.contrib.contenttypes.models import ContentType
from django.conf import settings

MODERATORS_PERMISSIONS = ['change_modelname', ]


def add_permissions(apps, schema_editor):
    apps.models_module = True
    create_permissions(apps, verbosity=0)
    apps.models_module = None

    moderators_group = Group.objects.get_or_create(
        name=settings.MODERATORS_GROUP)[0]
    for codename in MODERATORS_PERMISSIONS:
        permission = Permission.objects.get(codename=codename)
        moderators_group.permissions.add(permission)


class Migration(migrations.Migration):

    dependencies = [
        ('contenttypes', '0002_remove_content_type_name'),
        ('thisappname', '0001_initial'),
    ]

    operations = [
        migrations.RunPython(add_permissions),
    ]

And if you want something that will work on any version (or that will keep working when you upgrade):

from django.contrib.auth.management import create_permissions

version = django.VERSION
if version[0] >= 1 and django.VERSION[1] > 9:
    for app_config in apps.get_app_configs():
        app_config.models_module = True
        create_permissions(app_config, apps=apps, verbosity=0)
        app_config.models_module = None
else:
    apps.models_module = True
    create_permissions(apps, verbosity=0)
    apps.models_module = None

Trying to get an permission during migrations causes an exception(Permission matching query does not exist) in Django. It's an old problem in Django. In 1.6 version I solved it via @int_ua's snippet but in 1.11 version it doesn't work(I'm not sure why).

I used this workaround in 1.11 version:

def _assign_group_permissions(permission_codenames, apps, group_name):
    permission_list = []
    Permission = apps.get_model('auth', 'Permission')

    for permission_codename in permission_codenames:
        for permission in Permission.objects.all():
            if permission.codename == permission_codename:
                permission_list.append(permission)

    Group = apps.get_model('auth', 'Group')
    group = Group.objects.get(name=group_name)
    group.permissions.add(*permission_list)

Instead of Permission.objects.get(codename='your_code_name') it's possible to iterate over all permissions and choose suitable one by codename.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!