Python Django 1.7数据迁移和用户组
我正在尝试使用django 1.7本机迁移系统实现数据迁移。这就是我所做的Python Django 1.7数据迁移和用户组,python,django,migration,Python,Django,Migration,我正在尝试使用django 1.7本机迁移系统实现数据迁移。这就是我所做的 # -*- coding: utf-8 -*- from __future__ import unicode_literals from django.db import migrations def create_basic_user_group(apps, schema_editor): """Forward data migration that create the basic_user group
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations
def create_basic_user_group(apps, schema_editor):
"""Forward data migration that create the basic_user group
"""
Group = apps.get_model('auth', 'Group')
Permission = apps.get_model('auth', 'Permission')
group = Group(name='basic_user')
group.save()
perm_codenames = (
'add_stuff',
'...',
)
# we prefere looping over all these in order to be sure to fetch them all
perms = [Permission.objects.get(codename=codename)
for codename in perm_codenames]
group.permissions.add(*perms)
group.save()
def remove_basic_user_group(apps, schema_editor):
"""Backward data migration that remove the basic_user group
"""
group = Group.objects.get(name='basic_user')
group.delete()
class Migration(migrations.Migration):
"""This migrations automatically create the basic_user group.
"""
dependencies = [
]
operations = [
migrations.RunPython(create_basic_user_group, remove_basic_user_group),
]
但是当我尝试运行迁移时,我得到一个LookupError异常,告诉我找不到标签为“auth”的应用程序
我如何才能以一种干净的方式创建组,以便也可以在单元测试中使用?因此,我找到了解决此问题的方法,并获得了以下退出:get_model将仅获取您的模型应用程序。我不确定这是否是一个好的做法,但它对我起了作用 我只是直接调用了模型并进行了更改
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
from django.contrib.auth.models import Group
def create_groups(apps, schema_editor):
g = Group(name='My New Group')
g.save()
class Migration(migrations.Migration):
operations = [
migrations.RunPython(create_groups)
]
然后,只需应用/manage.py migrate即可完成。
我希望这会有帮助。我已经做了你想做的事。问题是:
RunPython
函数时,如果该函数使用的模型来自迁移所在应用程序以外的应用程序,则迁移的dependencies属性应包括所涉及的每个应用程序的最新迁移,否则,当您尝试使用apps.get_model()
在RunPython
函数中检索模型时,可能会出现类似以下错误:LookupError:No installed app with label'myappname'
因此,您应该依赖于auth
中的最新迁移post\u migrate
信号的信号处理程序创建的。因此,在迁移完成之前,与迁移中创建的任何新模型相关联的权限都不可用
您可以在create\u basic\u user\u group
的开头执行此操作来解决此问题:
from django.contrib.contenttypes.management import update_contenttypes
from django.apps import apps as configured_apps
from django.contrib.auth.management import create_permissions
for app in configured_apps.get_app_configs():
update_contenttypes(app, interactive=True, verbosity=0)
for app in configured_apps.get_app_configs():
create_permissions(app, verbosity=0)
这还将为每个模型创建内容类型(也是在迁移之后创建的),请参见下文,了解您为什么应该关注这些
也许在上面的代码中,你可以比我更具选择性:只更新一些关键应用程序,而不是更新所有应用程序。我没有试着选择。此外,两个循环也可能合并为一个。我还没有试过一个圈codename
可以获得权限
对象,但codename
不保证唯一。两个应用程序可以具有名为Stuff
的模型,因此您可以拥有与两个不同应用程序关联的add\u Stuff
权限。如果发生这种情况,代码将失败。您应该做的是按codename
和content\u type
进行搜索,这两种方法保证在一起是唯一的。一个独特的内容类型
与项目中的每个模型相关联:两个同名但在不同应用中的模型将获得两种不同的内容类型
这意味着添加对contenttypes
应用程序的依赖项,并使用ContentType
模型:ContentType=apps.get_模型(“contenttypes”,“ContentType”)
post_migrate
但是Django上已经有一个helper函数来发送所需的信号:Django.core.management.sql.emit\u post\u migrate\u signal
在这里,它是这样工作的:
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
from django.core.management.sql import emit_post_migrate_signal
PERMISSIONS_TO_ADD = [
'view_my_stuff',
...
]
def create_group(apps, schema_editor):
# Workarounds a Django bug: https://code.djangoproject.com/ticket/23422
db_alias = schema_editor.connection.alias
try:
emit_post_migrate_signal(2, False, 'default', db_alias)
except TypeError: # Django < 1.8
emit_post_migrate_signal([], 2, False, 'default', db_alias)
Group = apps.get_model('auth', 'Group')
Permission = apps.get_model('auth', 'Permission')
group, created = Group.objects.get_or_create(name='MyGroup')
permissions = [Permission.objects.get(codename=i) for i in PERMISSIONS_TO_ADD]
group.permissions.add(*permissions)
class Migration(migrations.Migration):
dependencies = [
('auth', '0001_initial'),
('myapp', '0002_mymigration'),
]
operations = [
migrations.RunPython(create_group),
]
#-*-编码:utf-8-*-
从未来导入unicode文字
从django.db导入模型、迁移
从django.core.management.sql导入发出\u post\u migrate\u信号
权限添加=[
“查看我的东西”,
...
]
def创建组(应用程序、架构编辑器):
#解决Django bug的方法:https://code.djangoproject.com/ticket/23422
db_alias=schema_editor.connection.alias
尝试:
发出后迁移信号(2,False,“default”,db\u别名)
除类型错误外:#Django<1.8
发出后迁移信号([],2,False,“default”,db\u别名)
Group=apps.get_model('auth','Group'))
权限=应用程序。获取模型('auth','Permission'))
group,created=group.objects.get\u或\u create(name='MyGroup')
权限=[Permission.objects.get(codename=i)for i in permissions\u TO\u ADD]
group.permissions.add(*权限)
类迁移(migrations.Migration):
依赖项=[
(‘auth’,‘0001_首字母’),
('myapp','0002_mymigration'),
]
操作=[
RunPython(创建组),
]
尝试应用程序。注册应用程序模式和/或依赖('auth','group')
。这是一个随机的建议,因为我自己还在理解注册表的内容。不过,它帮助我解决了一个类似的问题。在django 1.8中,对象管理器可以在迁移期间使用。尤其是现在,您的代码应该可以像此作品一样工作,但您不能向它们添加权限,因为它们是在迁移后创建的。事实上,如果您迁移一个已经存在的数据库,您会认为它是有效的,因为权限对象是在以前的迁移中创建的。但它将在针对新的空数据库的迁移中失败。