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.apps
在ready()
方法
默认流程为:
- 调用
migrate
命令
- 它执行迁移操作
post_migrate
发送信号并创建权限记录
所以我也可以写一个 post_migrate 函数,但是,我怎么能确定它会是 运行 在创建权限的默认函数之后?
其他问题:是否有更好的方法在首次迁移应用时自动分配权限?
提前致谢:)
目前似乎无法对权限创建采取行动,因为它们是在 post_migrate
信号中创建的(here) with the method bulk_create()。
参见 here。
- 解决这个问题的方法是使用 create() method instead. Which I tried to do by introducing a ticket on Django ticketing system (see here) and its 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()
该示例中有一些用于我的特定用例的蓬勃发展的东西,我可以根据用户需要在 运行 时间内 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。
我正在使用 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 函数,但是,我怎么能确定它会是 运行 在创建权限的默认函数之后?
其他问题:是否有更好的方法在首次迁移应用时自动分配权限?
提前致谢:)
目前似乎无法对权限创建采取行动,因为它们是在 post_migrate
信号中创建的(here) with the method bulk_create()。
参见 here。
- 解决这个问题的方法是使用 create() method instead. Which I tried to do by introducing a ticket on Django ticketing system (see here) and its 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()
该示例中有一些用于我的特定用例的蓬勃发展的东西,我可以根据用户需要在 运行 时间内 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。