【问题标题】:django: data migrate permissionsdjango:数据迁移权限
【发布时间】:2015-05-31 13:11:09
【问题描述】:

我有一堆需要迁移的新权限。我尝试通过数据迁移来做到这一点,但抱怨ContentType not being available

通过快速研究,我发现ContentType 表在应用了所有迁移后被填充。

我什至尝试使用来自from django.contrib.contenttypes.management import update_all_contenttypes update_all_contenttypes(),这会导致迁移加载与夹具不一致的数据。

在 Django 中迁移权限数据的最佳方法是什么?

【问题讨论】:

标签: django migration


【解决方案1】:

有两种方法可以解决这个问题:

1) 丑陋的方式:

在您想要的迁移之前运行manage.py migrate auth

2) 推荐方式:

from django.contrib.auth.management import create_permissions

def add_permissions(apps, schema_editor):
    apps.models_module = True

    create_permissions(apps, verbosity=0)
    apps.models_module = None

    # rest of code here....

【讨论】:

  • 另见sourcedjango.contrib.auth.management.create_permissions
【解决方案2】:

这是确保所有应用程序的所有权限都已创建的快速而肮脏的方法:

def add_all_permissions(apps=None, schema_editor=None):
    from django.contrib.auth.management import create_permissions

    if apps is None:
        from django.apps import apps

    for app_config in apps.get_app_configs():
        app_config.models_module = True
        create_permissions(app_config, verbosity=0)
        app_config.models_module = None

class Migration(migrations.Migration):
    dependencies = [('myapp', '0123_do_the_thing')]
    operations = [
        migrations.RunPython(add_all_permissions, 
                             reverse_code=migrations.RunPython.noop)
        # ...
    ]

注意:已编辑以包含 ruohola 的出色建议

【讨论】:

  • 你会在哪里添加这个?
  • 这将进入数据迁移(文件中的任何位置)并在 RunPython 方法的开头调用
  • 最好弄成def add_all_permissions(apps, schema_editor):,然后就不用导入apps了。然后可以使用migrations.RunPython(code=add_all_permission)
【解决方案3】:

以下是向User 模型添加自定义权限的步骤:

首先创建一个迁移文件,例如在你的认证应用下,

这里我把它命名为0002_permission_fixtures.py:

account (your authentication application)
 |_migrations
   |__ 0001_initial.py
   |__ 0002_permission_fixtures.py
   |__ __init__.py

然后添加你的权限对象,如下:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations


def forwards_func(apps, schema_editor):
    # Get models that we needs them
    user = apps.get_model("auth", "User")
    permission = apps.get_model("auth", "Permission")
    content_type = apps.get_model("contenttypes", "ContentType")
    # Get user content type object
    uct = content_type.objects.get_for_model(user)
    db_alias = schema_editor.connection.alias
    # Adding your custom permissions to User model: 
    permission.objects.using(db_alias).bulk_create([
        permission(codename='add_sample', name='Can add sample', content_type=uct),
        permission(codename='change_sample', name='Can change sample', content_type=uct),
        permission(codename='delete_sample', name='Can delete sample', content_type=uct),
    ])


class Migration(migrations.Migration):
    dependencies = [
    ('contenttypes', '__latest__'),
            ]

    operations = [
        migrations.RunPython(
            forwards_func,
        ),
    ]

要运行此迁移,首先迁移contenttype 模型,然后迁移您的应用程序(这里是帐户)。

$ python manage.py migrate contenttypes
$ python manage.py migrate account

【讨论】:

  • 使用“示例”内容类型而不是用户内容类型不是更好吗?
猜你喜欢
  • 1970-01-01
  • 2018-06-22
  • 1970-01-01
  • 2019-09-29
  • 1970-01-01
  • 2015-10-13
  • 2019-10-16
  • 2018-03-04
  • 1970-01-01
相关资源
最近更新 更多