我一直试图在Django Auth文档中找到答案,但似乎无法找到我要找的东西。
我遇到的问题是,当我定义添加组的代码时(与管理页面中的组相同):
#read_only
group, created = Group.objects.get_or_create(name='read_only')
if created:
group.permissions.add(can_read_campaign)
logger.info('read_only_user Group created')
#standard
group, created = Group.objects.get_or_create(name='standard_user')
if created:
group.permissions.add(can_edit_users)
logger.info('standard_user Group created')
#admin
group, created = Group.objects.get_or_create(name='admin_user')
if created:
group.permissions.add(can_edit_campaign, can_edit_users)
logger.info('admin_user Group created')
当我在models.py和 init .py中运行此代码时,他们都给了我这个错误:
django.core.exceptions.AppRegistryNotReady
我认为这是因为Model / init 试图过早地将内容插入django app / admin?
如何以编程方式添加这些组?
编辑:
这不是一个重复的问题,这实际上是在项目设置期间在模型中添加权限和组,而不是通过shell。
我通过使用信号和接收器(django模块)解决了这个问题。
我添加了代码以将权限/组创建到其自己的函数中,并使用接收器(post_migrate)对其进行修饰,该接收器将在迁移完成后运行此函数,从而消除此错误。
@receiver(post_migrate)
def init_groups(sender, **kwargs):
#permission and group code goes here
答案 0 :(得分:23)
我被推荐this方式来做到这一点:
在相应的模块中创建虚假迁移:
python manage.py makemigrations --empty yourappname
打开已创建的文件,该文件应如下所示:
# -*- coding: utf-8 -*-
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('yourappname', '0001_initial'),
]
operations = [
]
并添加您的代码:
# -*- coding: utf-8 -*-
from django.db import models, migrations
def add_group_permissions():
#read_only
group, created = Group.objects.get_or_create(name='read_only')
if created:
group.permissions.add(can_read_campaign)
logger.info('read_only_user Group created')
#standard
group, created = Group.objects.get_or_create(name='standard_user')
if created:
group.permissions.add(can_edit_users)
logger.info('standard_user Group created')
#admin
group, created = Group.objects.get_or_create(name='admin_user')
if created:
group.permissions.add(can_edit_campaign, can_edit_users)
logger.info('admin_user Group created')
class Migration(migrations.Migration):
dependencies = [
('yourappname', '0001_initial'),
]
operations = [
migrations.RunPython(add_group_permissions),
]
最后,运行迁移:
python manage.py migrate
这很好,因为您可以部署到Heroku或任何地方,并确保它将被应用,因为它只是另一次迁移。
答案 1 :(得分:3)
将@Robert Grant和this结合起来就可以做到:
python manage.py makemigrations --empty yourappname
然后:
from django.contrib.auth.models import Group, Permission
from django.db import models, migrations
import logging
logger = logging.getLogger(__name__)
campaign_group_permissions = {
"Campaign Manager": [
"add_campaign",
"change_campaign",
"delete_campaign",
"view_campaign",
"add_campaignsms",
"add_sending",
"change_sending",
"view_sending"
]
}
def add_group_permissions():
# See https://code.djangoproject.com/ticket/23422
db_alias = schema_editor.connection.alias
try:
emit_post_migrate_signal(2, False, 'default')
except TypeError: # Django < 1.8
emit_post_migrate_signal([], 2, False, 'default', db_alias)
for group in campaign_group_permissions:
role, created = Group.objects.get_or_create(name=group)
logger.info(f'{group} Group created')
for perm in campaign_group_permissions[group]:
role.permissions.add(Permission.objects.get(codename=perm))
logger.info(f'Permitting {group} to {perm}')
role.save()
class Migration(migrations.Migration):
dependencies = [
('yourappname', '0001_initial'),
]
operations = [
migrations.RunPython(add_group_permissions),
]
注意:,该功能可在Django 3.x上使用,但我很确定它也将在Django 1.7上使用。
答案 2 :(得分:2)
@Ruloweb 的精彩回复几乎对我有用,但我必须进行一些调整才能使其在具有多个应用程序的 Django 3.1 中工作。
首先,我需要向 add_group_permissions() 函数添加参数。我还需要导入emit_post_migration_signal:
from django.contrib.auth.models import Group, Permission
from django.core.management.sql import emit_post_migrate_signal # <-- Added this
from django.db import models, migrations
import logging
logger = logging.getLogger(__name__)
public_group_permissions = {
"Your permission group name here": ['your permissions here']
}
def add_group_permissions(apps, schema_editor): # <-- updated this
# See https://code.djangoproject.com/ticket/23422
db_alias = schema_editor.connection.alias
try:
emit_post_migrate_signal(2, False, 'default')
except TypeError: # Django < 1.8
emit_post_migrate_signal([], 2, False, 'default', db_alias)
for group in public_group_permissions:
role, created = Group.objects.get_or_create(name=group)
logger.info(f'{group} Group created')
for perm in public_group_permissions[group]:
role.permissions.add(Permission.objects.get(codename=perm))
logger.info(f'Permitting {group} to {perm}')
role.save()
class Migration(migrations.Migration):
dependencies = [
('your_app_name', '0001_initial'),
]
operations = [
migrations.RunPython(add_group_permissions),
]