时不时地,您需要在 Django 中重命名模型(或者,在我最近遇到的一个案例中,将一个模型分成两个,使用新的/不同的名称)。(是的,适当的计划有助于避免这种情况)。
在重命名数据库中的相应表并修复受影响的代码后,仍然存在一个问题:授予用户或组对这些模型进行操作的任何权限仍然引用旧模型名称。是否有任何自动化或半自动化的方法来解决这个问题,还是只是手动数据库手术的问题?(在开发中,您可以删除 auth_permissions 表和 syncdb 以重新创建它,但生产并不那么简单)。
时不时地,您需要在 Django 中重命名模型(或者,在我最近遇到的一个案例中,将一个模型分成两个,使用新的/不同的名称)。(是的,适当的计划有助于避免这种情况)。
在重命名数据库中的相应表并修复受影响的代码后,仍然存在一个问题:授予用户或组对这些模型进行操作的任何权限仍然引用旧模型名称。是否有任何自动化或半自动化的方法来解决这个问题,还是只是手动数据库手术的问题?(在开发中,您可以删除 auth_permissions 表和 syncdb 以重新创建它,但生产并不那么简单)。
这里是一个填充缺少的内容类型和权限的片段。我想知道它是否可以扩展到至少做一些清理 auth_permissions 的工作。
如果您碰巧使用了 South 模式迁移来重命名表,则正向迁移中的以下行将自动完成此操作:
db.send_create_signal('appname', ['modelname'])
我做了一个很长的回答,详细说明了在这种情况下我将采取的攻击计划,但在我写这篇文章的时候,我意识到在这种情况下可能没有任何办法可以避免停机维护。
当然,您可以通过准备好 loaddata 脚本来最大程度地减少停机时间,尽管需要注意确保 auth_perms 主键是同步的。
另请参阅简短答案:我知道没有自动执行此操作的方法。
我最近遇到了这个问题并写了一个函数来解决它。如果重命名模型/表,通常会与 ContentType 和 Permission 表存在差异。Django 有内置的帮助函数来解决这个问题,你可以按如下方式使用它们:
from django.contrib.auth.management import create_permissions
from django.contrib.contenttypes.management import update_all_contenttypes
from django.db.models import get_apps
def update_all_content_types_and_permissions():
for app in get_apps():
create_permissions(app, None, 2)
update_all_contenttypes()
我在应用程序中更改了详细名称,在 Django 2.2.7 中,这是我发现修复权限的唯一方法:
from django.core.management.base import BaseCommand, CommandError
from django.contrib.auth.models import Permission
class Command(BaseCommand):
help = 'Fixes permissions names'
def handle(self, *args, **options):
for p in Permission.objects.filter(content_type__app_label="your_app_label_here"):
p.name = "Can %s %s"%(p.codename.split('_')[0], p.content_type.model_class()._meta.verbose_name)
p.save()