Django:初始迁移后如何自动分配权限

Django : how to assign permissions automatically after initial migration

我正在使用 Django 作为后端,一切正常。 但是我现在必须启用权限等等。 我试图在迁移过程中将一个应用程序的所有权限分配给一个组,但问题是:

在初始迁移期间,尚未创建权限。原因是在 Django 中,它们是在 post_migrate 信号中创建的。

参见:

def ready(self):
   post_migrate.connect(
       create_permissions,
       dispatch_uid="django.contrib.auth.management.create_permissions"
   )
   # ...

django.contrib.auth.appsready()方法

默认流程为:

所以我也可以写一个 post_migrate 函数,但是,我怎么能确定它会是 运行 在创建权限的默认函数之后?

其他问题:是否有更好的方法在首次迁移应用时自动分配权限?

提前致谢:)

目前似乎无法对权限创建采取行动,因为它们是在 post_migrate 信号中创建的(here) with the method bulk_create()

参见 here

  1. 解决这个问题的方法是使用 create() method instead. Which I tried to do by introducing a ticket on Django ticketing system (see here) and its PR.
  2. 第二种方法(只要维护 bulk_create() 来创建权限,我就会使用它)是 运行 ready() 方法中的一个方法 (...)分配给他们。

对于 2) 解决方案,我最终得到了这个:

def distribute_base_permissions():
    """ This method is used to automatically grant permissions of 'base' application
        to the 'Administrator' Group.
    """
    from django.contrib.auth.models import Group, Permission
    from django.contrib.contenttypes.models import ContentType
    group_content_type = ContentType.objects.get_for_model(Group)
    group, created = Group.objects.get_or_create(name="Administrator")
    for model in ContentType.objects.filter(app_label="base"):
        for perm in Permission.objects.filter(content_type__in=[model, group_content_type]):
            if (not group.has_permission(perm.codename) and
                perm.codename not in model.model_class().UNUSED_PERMISSIONS):
                group.add_permissions([perm])


class BaseConfig(AppConfig):
    name = 'backend.base'

    def ready(self):
        distribute_base_permissions()

该示例中有一些用于我的特定用例的蓬勃发展的东西,我可以根据用户需要在 运行 时间内 install/uninstall 应用程序。

我的 base 应用程序是默认安装的,因此可以像这样分配它的权限。

对于我的可安装应用程序,它几乎相同,只是它不是在 ready() 方法中完成的,而是在我的自定义安装过程结束时完成的:

class Application(models.Model):

    class Meta:
        db_table = "base_application"
        verbose_name = "Application"

    # ...
    def migrate_post_install(self):
        # ...
        self.distribute_permissions()

    def distribute_permissions(self):
        """ This method is used to automatically grant permissions of the installed
            application to the 'Administrator' Group.
        """
        group, created = Group.objects.get_or_create(name="Administrator")
        for model in ContentType.objects.filter(app_label=self.name):
            for perm in Permission.objects.filter(content_type=model):
                if (not group.has_permission(perm.codename) and
                    perm.codename not in model.model_class().UNUSED_PERMISSIONS):
                    group.add_permissions([perm])

编辑:

解决方案 1) 已被拒绝,因为可以看到 here。 讨论的解决方案是添加一个 post_migrate 处理程序,但由于权限创建已经在 post_migrate 中完成,我不知道如何确定我的信号处理程序将是 运行 在创建权限之后...

否则,似乎正在进行更改权限创建过程的工作,如图所示 here