目前似乎不可能对 Permission 创建采取行动,因为它们是使用 bulk_create() 方法在 post_migrate 信号 (here) 中创建的。
见here。
- 解决此问题的一种方法是改用create() 方法。我试图通过在 Django 票务系统(参见here)及其PR 上引入一张票来做到这一点。
- 第二种方法(只要维护
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()
该示例中有一些用于我的特定用例的精彩内容,我可以在运行时根据用户需要安装/卸载应用程序。
我的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所示。