【问题标题】:How to reference generated permissions in Django 1.7 migrations如何在 Django 1.7 迁移中引用生成的权限
【发布时间】:2015-03-29 09:40:52
【问题描述】:

我正在尝试使用迁移自动创建具有权限的 auth.Group。我的问题是,当我在空数据库上运行迁移时,尝试将权限附加到组的迁移找不到权限。如果我以较早的迁移为目标,以便迁移退出而不会出现错误,则权限会出现在数据库中,之后迁移代码可以找到权限。那么,当迁移背靠背运行时,我该怎么做才能让迁移引用在早期迁移中创建的权限?

def load_data(apps, schema_editor):
    Permission  = apps.get_model('auth', 'Permission')
    Group       = apps.get_model('auth', 'Group')

    can_add = Permission.objects.get(codename='add_game')
    developers = Group.objects.create(name='Developer')

    developers.permissions.add(can_add)
    developers.save()


class Migration(migrations.Migration):

    dependencies = [
        ('myApp', '0004_game'),
    ]

    operations = [
        migrations.RunPython(load_data),
    ]

游戏模型是在较早的迁移中创建的。当我在空数据库上运行其他迁移时,此代码总是会导致错误,指出权限匹配查询不存在。 我正在使用 python 3.4 和 django 1.7.2

【问题讨论】:

  • add_game 权限在0004_game 迁移中创建的吗?
  • 这是为每个模型(添加、更改、删​​除)创建的默认权限之一。如果迁移目标为0004_game,它会在0004_game 的数据库中创建,但如果所有迁移都在空数据库上连续运行,则0005 迁移找不到权限。

标签: python django permissions migration


【解决方案1】:

哦。 4年后... 要创建权限,Django 使用post_migrate 信号。

因此,当一次运行所有迁移时,权限尚不存在。

因此,你可以取出你的函数,例如在管理命令中。

但是,您仍然可以这样做:

from django.contrib.auth.management import create_permissions


APPS = [
    ...your app labels
]


def create_applications_permissions():
    for app in APPS:
        app_config = django_apps.get_app_config(app)
        create_permissions(app_config)


def load_data(apps, schema_editor):
    create_applications_permissions()
    Permission  = apps.get_model('auth', 'Permission')
    Group       = apps.get_model('auth', 'Group')

    can_add = Permission.objects.get(codename='add_game')
    developers = Group.objects.create(name='Developer')

    developers.permissions.add(can_add)
    developers.save()


class Migration(migrations.Migration):

    dependencies = [
        ('myApp', '0004_game'),
    ]

    operations = [
        migrations.RunPython(load_data),
    ]

并且要创建权限,请不要使用传递给迁移的应用程序。不会通过create_permissions的检查:

if not app_config.models_module:
    return

但你必须小心。

希望有人有用。

【讨论】:

  • 如果我只有一个应用怎么办?
  • 在 Django 3.2.5+ 中,将 ("contenttypes", "0002_remove_content_type_name") 添加到您的依赖项中。已添加迁移 (0002) 删除“名称”字段。此迁移在迁移树中相当低,因此在创建权限时可能尚未应用,导致 django.db.utils.IntegrityError: null value in column "name" of relationship "django_content_type" 违反非空约束详细信息: 失败行包含 (1, null, admin, logentry)
  • 事实上.. 只需添加 ("auth", "0012_alter_user_first_name_max_length") (或任何适合您的用例)。这样你就可以确定 Permissions 和 ContentType 存在
猜你喜欢
  • 2014-05-28
  • 2014-12-13
  • 2014-07-08
  • 2018-06-22
  • 2014-10-25
  • 1970-01-01
  • 2015-05-31
  • 2015-10-31
  • 2015-02-09
相关资源
最近更新 更多