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

问题描述

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

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

见:

post_migrate

def ready(self): post_migrate.connect( create_permissions,dispatch_uid="django.contrib.auth.management.create_permissions" ) # ... 方法中的 django.contrib.auth.apps

认流程是:

  • 调用 ready() 命令
  • 它负责迁移工作
  • migrate 信号已发送并创建权限记录

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

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

提前致谢:)

解决方法

目前似乎无法对权限创建进行操作,因为它们是在 post_migrate 信号 (here) 中使用 bulk_create() 方法创建的。

here

  1. 解决此问题的一种方法是改用 create() 方法。我试图通过在 Django 票务系统(见 here)及其 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
    from .models.base_application import Application
    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()

该示例中有一些非常有用的东西,用于我的特定用例,我可以在运行时根据用户需要安装/卸载应用程序。

我的 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 所示。