一部の権限を更新するデータ移行があります。移行の権限には既知の問題がいくつかあることはわかっています。移行の権限を自分で作成することで問題を回避できました(モデルのタプルショートカットを使用するのではなく)。
移行:
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
がないことがわかりました(理由は不明)。これのアドバイスに従って post 移行自体でコンテンツタイプを手動で更新してみました。追加:
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'
テスト可能な方法でデータ移行の権限を作成/更新するsome方法が必要です。
ありがとう。
[〜#〜]編集[〜#〜]
最後にそれを追加することによってそれを機能させました
from Django.contrib.contenttypes.management import update_all_contenttypes
update_all_contenttypes()
奇妙なことに、これは十分ではありませんでした
update_contenttypes(apps.app_configs['contenttypes'])
なぜこれがすべて必要なのか知りたい
答えは:
apps.get_model('contenttypes', 'ContentType')
:)今日は自分で必要でした。
複数のアプリにまたがるデータ移行を作成するときに同様の問題が発生します。 Djangoは、移行の「依存関係」メンバーの状態に影響を受けるモデルのみをアプリレジストリにロードします: https://code.djangoproject.com/ticket/243
基本的に、私が使用する移行の依存関係にエントリを追加する必要がありました。現在移行中のアプリへの外部キー。
それ以来、私はこれに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)
]
Django 2.1の場合、移行に渡されたアプリがDjango.db.migrations.state.AppConfigStub
のインスタンスであり、models_module
属性が設定されていないため、グローバルレジストリからアプリをインポートする必要がありました。 。そしてcreate_contenttypes
がこの属性をチェックしています。
from Django.apps.registry import Apps, apps as global_apps
from Django.contrib.contenttypes.management import create_contenttypes
from Django.db import migrations
def add_permision(apps: Apps, schema_editor):
gls_app_config = global_apps.get_app_config('my_app')
create_contenttypes(gls_app_config)
...
update_contenttypes(apps.app_configs['contenttypes'])
contenttypesアプリのコンテンツタイプを更新します。
あなたはこれをしたいと思うでしょう...
update_contenttypes(apps.app_configs['app_label'])
ここで、app_labelは、招待モデルが存在するアプリのアプリラベルです。これにより、単一のアプリのコンテンツタイプが更新され、元のコードに従ってクエリで使用できるようになります。