43

一部の権限を更新するデータ移行があります。移行のアクセス許可にはいくつかの既知の問題があることを知っており、移行自体でアクセス許可を作成することで (モデルでタプル ショートカットを使用するのではなく)、いくつかの問題を回避できました。

移行:

from __future__ import unicode_literals
from django.db import migrations, models
from django.conf import settings

def create_feature_groups(apps, schema_editor):
    app = models.get_app('myauth')

    Group = apps.get_model("auth", "Group")
    pro = Group.objects.create(name='pro')

    Permission = apps.get_model("auth", "Permission")
    ContentType = apps.get_model("contenttypes", "ContentType")
    invitation_contenttype = ContentType.objects.get(name='Invitation')

    send_invitation = Permission.objects.create(
         codename='send_invitation',
         name='Can send Invitation',
         content_type=invitation_contenttype)

    pro.permissions.add(receive_invitation)    

class Migration(migrations.Migration):

    dependencies = [
        ('myauth', '0002_initial_data'),
    ]

    operations = [
            migrations.RunPython(create_feature_groups),
    ]

いくつかの試行錯誤の後、私はこれを使用して機能させることができましたmanage.py migrateが、テストでエラーが発生していますmanage.py test

__fake__.DoesNotExist: ContentType matching query does not exist.

ContentTypeテストで実行すると、移行のこの時点で何もないことが少し発見されました(理由はわかりません)。この投稿のアドバイスに従って、移行自体でコンテンツ タイプを手動で更新しようとしました。追加した :

from django.contrib.contenttypes.management import update_contenttypes
update_contenttypes(app, models.get_models())

Invitationモデルのコンテンツ タイプを取得する前。次のエラーが発生しました

  File "C:\Python27\lib\site-packages\django-1.7-py2.7.egg\django\contrib\contenttypes\management.py", line 14, in update_contenttypes
    if not app_config.models_module:
AttributeError: 'module' object has no attribute 'models_module'

テスト可能な方法でデータ移行の権限を作成/更新する何らかの方法が必要です。

ありがとう。

編集

最後に追加して機能させました

from django.contrib.contenttypes.management import update_all_contenttypes
update_all_contenttypes() 

奇妙なことに、これは十分ではありませんでした

update_contenttypes(apps.app_configs['contenttypes'])

なぜこれがすべて必要なのか知りたいです

4

6 に答える 6

7

私はこれに3〜4時間を費やしてしまったので、ソリューションを追加しています。

問題は、複数の移行を一緒に実行したときに ContentType オブジェクトと Permission オブジェクトが作成されないことでした。これらのコンテンツ タイプと移行を次の移行で参照していたため、これが問題を引き起こしていました。)

ただし、移行番号を使用して 1 つずつ実行すると、正常に動作します。(将来の移行で参照されました)

それを解決するために、ContentType オブジェクトと Permission オブジェクトを作成するために間に追加の移行を追加しました。

# -*- coding: utf-8 -*-
# Generated by Django 1.10.6 on 2017-03-11 05:59
from __future__ import unicode_literals

from django.conf import settings
from django.db import migrations


def update_all_contenttypes(**kwargs):
    from django.apps import apps
    from django.contrib.contenttypes.management import update_contenttypes

    for app_config in apps.get_app_configs():
        update_contenttypes(app_config, **kwargs)


def create_all_permissions(**kwargs):
    from django.contrib.auth.management import create_permissions
    from django.apps import apps

    for app_config in apps.get_app_configs():
        create_permissions(app_config, **kwargs)


def forward(apps, schema_editor):
    update_all_contenttypes()
    create_all_permissions()


def backward(apps, schema_editor):
    pass


class Migration(migrations.Migration):
    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
        ('contenttypes', '0002_remove_content_type_name'),
        ('MY_APP', '0123_LAST_MIGRATION'),
    ]

    operations = [
        migrations.RunPython(forward, backward)
    ]
于 2017-03-14T16:19:30.953 に答える
1
update_contenttypes(apps.app_configs['contenttypes'])

contenttypes アプリのコンテンツ タイプを更新します。

私はあなたがこれをやりたいと思うと信じています...

update_contenttypes(apps.app_configs['app_label']) 

ここで、app_label は Invitation モデルが存在するアプリのアプリ ラベルです。これにより、単一のアプリのコンテンツ タイプが更新され、元のコードに従ってクエリできるようになります。

于 2016-06-28T10:01:54.950 に答える