hak*_*aki 39 django django-1.7 django-migrations
我有一个数据迁移,可以更新一些权限.我知道迁移中的权限存在一些已知问题,我可以通过自己的迁移(而不是使用模型中的元组快捷方式)创建权限来避免一些麻烦.
迁移:
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),
]
Run Code Online (Sandbox Code Playgroud)
经过一些试验和错误,我能够使用这项工作,manage.py migrate但我在测试中遇到错误manage.py test.
__fake__.DoesNotExist: ContentType matching query does not exist.
Run Code Online (Sandbox Code Playgroud)
稍微调试发现,ContentType在测试中运行时,迁移中此时没有(不确定原因).按照这篇文章中的建议,我尝试在自己的迁移中手动更新内容类型.添加 :
from django.contrib.contenttypes.management import update_contenttypes
update_contenttypes(app, models.get_models())
Run Code Online (Sandbox Code Playgroud)
在获取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'
Run Code Online (Sandbox Code Playgroud)
必须有一些方法以可测试的方式在数据迁移中创建/更新权限.
谢谢.
编辑
最后通过添加使其工作
from django.contrib.contenttypes.management import update_all_contenttypes
update_all_contenttypes()
Run Code Online (Sandbox Code Playgroud)
奇怪的是这个还不够
update_contenttypes(apps.app_configs['contenttypes'])
Run Code Online (Sandbox Code Playgroud)
我很想知道为什么所有这些都是必要的
Pet*_*ryl 10
对于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):
my_app_config = global_apps.get_app_config('my_app')
create_contenttypes(my_app_config)
...
Run Code Online (Sandbox Code Playgroud)
编写跨越多个应用程序的数据迁移时遇到类似问题.事实证明,Django只会将这些模型加载到受迁移状态的"依赖关系"成员影响的应用程序注册表中:https://code.djangoproject.com/ticket/24303
不得不基本上添加一个条目,我使用的迁移依赖项与例如ForeignKey没有直接关联到当前正在迁移的应用程序.
从那以后,我最终花了3-4个小时才加入我的解决方案.
问题是当我一起运行多个迁移时,没有创建ContentType和Permission对象.由于我在下次迁移时引用了这些内容类型和迁移,这导致了问题.)
但是,如果我使用迁移号逐个运行它们,它们可以正常工作.(在将来的迁移中引用)
为了解决这个问题,我在其间添加了一个额外的迁移来创建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)
]
Run Code Online (Sandbox Code Playgroud)
答案是:
apps.get_model('contenttypes', 'ContentType')
Run Code Online (Sandbox Code Playgroud)
:)今天我自己需要它。
| 归档时间: |
|
| 查看次数: |
8026 次 |
| 最近记录: |