【问题标题】:Django 1.7 where to put the code to add Groups programmatically?Django 1.7 将代码放在哪里以编程方式添加组?
【发布时间】:2014-09-21 09:14:22
【问题描述】:

我一直试图在 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 应用程序/管理员?

如何以编程方式添加这些组?

编辑:

这不是一个重复的问题,这实际上是在项目设置期间在模型中添加权限和组,而不是通过 shell。

我已经通过使用信号和接收器(django 模块)解决了这个问题。

我将用于创建权限/组的代码添加到它自己的函数中,并用接收器 (post_migrate) 对其进行修饰,它将在迁移完成后运行此函数,从而消除此错误。

@receiver(post_migrate)
def init_groups(sender, **kwargs):
    #permission and group code goes here

【问题讨论】:

  • 您需要调用setup()函数。我会将此作为重复项关闭 - 让我们知道它是否真的不止于此。
  • 嗨@alecxe,这不是一个重复的问题,我已经为你提供了一个编辑。

标签: python django django-models django-admin


【解决方案1】:

我被推荐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 或任何地方,并确保它会被应用,因为这只是另一个迁移。

【讨论】:

  • 不错的答案,非常巧妙的方法。
  • 只是一个改进:def create_group(name, perms=[]): group, created = Group.objects.get_or_create(name=name) if created: for perm in perms: group.permissions.add (perm) logger.info("组\"" + name + "\" created")
  • 在 Django 1.8 中,我必须在这个答案中添加两件事:from django.contrib.auth.models import Group 在顶部,否则它会抱怨未定义组。然后函数定义需要两个参数:def add_group_permissions(apps, schema_editor):.
  • 在 django 1.9.5 中,尝试在迁移期间获取权限会导致我出现错误stackoverflow.com/questions/38491215/…
【解决方案2】:

结合@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。

【讨论】:

    【解决方案3】:

    @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),
        ]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-07
      • 1970-01-01
      • 2012-02-26
      • 2018-07-05
      • 2015-03-11
      • 1970-01-01
      相关资源
      最近更新 更多