Programmatically creating a group : Can't acce

2020-04-10 06:38发布

After seeing this post, I tried to create my own group at project setup with this migration :

from django.db import migrations
from django.contrib.auth.models import Group, Permission

def create_group(apps, schema_editor):
    group, created = Group.objects.get_or_create(name='thing_managers')
    if created:
        add_thing = Permission.objects.get(codename='add_thing')
        group.permissions.add(add_thing)
        group.save()

class Migration(migrations.Migration):

    dependencies = [
        ('main', '0002_auto_20160720_1809'),
    ]

    operations = [
        migrations.RunPython(create_group),
    ]

But I got the following error :

django.contrib.auth.models.DoesNotExist: Permission matching query does not exist.

Here is my model :

class Thing(models.Model):
    pass

Why can't I do that? How could I solve this?

I use django 1.9.

3条回答
Animai°情兽
2楼-- · 2020-04-10 06:57

One solution is call the update_permissions command before try to append a permission

from django.core.management import call_command

def update_permissions(schema, group):
    call_command('update_permissions')


operations = [
        migrations.RunPython(update_permissions, reverse_code=migrations.RunPython.noop),
        migrations.RunPython(create_group),
    ]

And as was commented don't import Group and Permission models use:

Group = apps.get_model("auth","Group")
Permission = apps.get_model("auth","Permission")
查看更多
萌系小妹纸
3楼-- · 2020-04-10 07:05

From this Django ticket, here's what worked for me in Django 3.0.4 and apparently will work in >=1.9:

from django.core.management.sql import emit_post_migrate_signal

def create_group(apps, schema_editor):
    # Ensure permissions and content types have been created.
    db_alias = schema_editor.connection.alias
    emit_post_migrate_signal(2, False, db_alias)
    # Now the content types and permissions should exist

    Permission = apps.get_model('auth', 'Permission')
    ...
查看更多
看我几分像从前
4楼-- · 2020-04-10 07:06

Permissions are created in a post_migrate signal. They don't exist the first time migrations are run after a new model is added. It is probably easiest to run the post_migrate signal handler manually:

from django.contrib.auth.management import create_permissions

def create_group(apps, schema_editor):
    for app_config in apps.get_app_configs():
        create_permissions(app_config, apps=apps, verbosity=0)

    group, created = Group.objects.get_or_create(name='thing_managers')
    if created:
        add_thing = Permission.objects.get(codename='add_thing')
        group.permissions.add(add_thing)
        group.save()

create_permissions checks for existing permissions, so this won't create any duplicates.

查看更多
登录 后发表回答