【问题标题】:Fixing the auth_permission table after renaming a model in Django在 Django 中重命名模型后修复 auth_permission 表
【发布时间】:2009-02-27 07:12:52
【问题描述】:

有时,您需要在 Django 中重命名一个模型(或者,在我最近遇到的一个案例中,将一个模型分成两个,使用新的/不同的名称)。 (是的,适当的计划有助于避免这种情况)。

在重命名数据库中的相应表并修复受影响的代码后,仍然存在一个问题:授予用户或组对这些模型进行操作的任何权限仍然引用旧模型名称。是否有任何自动化或半自动化的方法来解决这个问题,还是只是手动数据库手术的问题? (在开发中您可以删除 auth_permissions 表并使用 syncdb 重新创建它,但生产并不那么简单)。

【问题讨论】:

  • 9 年后……你还记得你是怎么做到的吗?
  • 哈,不记得了,抱歉。此页面上的其他答案是否有帮助?如果您想出适用于 Django 2 的配方,请发布。
  • 在我的特殊情况下,我的 django 数据库填充了来自旧数据库的 ETL 脚本。我觉得修复权限之后会修复索引和 postgresql 序列等,我不想进入兔子洞。我最终清除了数据库,使用新数据库的新模型名称重新运行 django 迁移,然后重新运行 ETL 脚本

标签: django django-models


【解决方案1】:

这里是a snippet,用于填充缺失的内容类型和权限。我想知道它是否可以扩展到至少做一些清理 auth_permissions 的工作。

【讨论】:

【解决方案2】:

如果您碰巧使用了 South 模式迁移来重命名表,则正向迁移中的以下行会自动完成此操作:

db.send_create_signal('appname', ['modelname'])

【讨论】:

    【解决方案3】:

    我得到了一个很长的答案,详细说明了在这种情况下我将采取的攻击计划,但是当我写这篇文章时,我意识到在这种情况下可能没有任何办法可以避免停机维护.

    当然,您可以通过准备好 loaddata 脚本来最大程度地减少停机时间,但需要注意确保 auth_perms 主键同步。

    另见简短回答:据我所知,没有自动化的方法可以做到这一点。

    【讨论】:

      【解决方案4】:

      我最近遇到了这个问题并写了一个函数来解决它。如果重命名模型/表,通常会与 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 1.7):'module' object has no attribute 'models_module'
      【解决方案5】:

      我在应用程序中更改了详细名称,在 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()
      

      【讨论】:

        猜你喜欢
        • 2015-01-26
        • 2012-01-29
        • 2011-07-23
        • 2015-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-14
        • 2018-01-20
        相关资源
        最近更新 更多