我正在尝试按照此tutorial添加新的迁移
我在Meta
内向permissions
字段添加了新权限。然后我创建了迁移并尝试修改此迁移以更新组权限。但是在DoesNotExist
操作中获得RunPython
。
from django.db import migrations
def assign_new_permission(apps, *args):
Permission = apps.get_model('auth.Permission')
Group = apps.get_model('auth.Group')
# __fake__.DoesNotExist: Permission matching query does not exist.
new_permission = Permission.objects.get(
codename='my_new_permissoin_code')
admins = Group.objects.get(name='Group name')
admins.permissions.add(new_permission)
class Migration(migrations.Migration):
dependencies = [
('my_app', '0066_some_migratoin'),
]
operations = [
migrations.AlterModelOptions(
name='my_model',
options={'permissions': (('my_new_permissoin_code',
'Permission name'),)},
),
migrations.RunPython(assign_new_permission)
]
答案 0 :(得分:4)
我认为您的问题之所以出现,是因为实际上并不是在单个迁移期间或之后创建权限,而是由python manage.py migrate
命令成功完成后发送的迁移后信号触发的(请参见已接受的评论)。回答here。)
有几种解决方法:
将其分为两个单独的迁移(创建权限,然后分配它们),并使用两个单独的python manage.py migrate
命令运行它们:
python manage.py migrate my_app 0066_create_permissions
python manage.py migrate my_app 0067_assign_permissions
这允许运行0066创建权限后发出迁移后信号。
在一次迁移中将其分为两个步骤,但是您必须使用Python函数手动创建权限,然后在另一个函数中进行分配。您必须修改operations
才能解决此问题。这样的好处之一是,如果愿意,您还可以创建一个或多个Python函数来逆向迁移,这对于#3或#4而言实际上是不可能的。
在迁移期间自己发出迁移后的信号。对于需要第三方应用程序(例如django-guardian)的权限的情况,这是一个很好的解决方案,以便可以将其应用于数据迁移。
from django.apps import apps as django_apps
def guardian_post_migrate_signal(apps, schema_editor):
guardian_config = django_apps.get_app_config('guardian')
models.signals.post_migrate.send(
sender=guardian_config,
app_config=guardian_config,
verbosity=2,
interactive=False,
using=schema_editor.connection.alias,
)
这与#3相似,但要容易一些。可能有好还是坏的微妙方法,但是我不确定它们是什么。您可以创建一个调用django.contrib.auth.management.create_permissions
(贷记为this post)并直接在迁移中使用的函数:
from django.contrib.auth.management import create_permissions
def create_perms(apps, schema_editor):
for app_config in apps.get_app_configs():
app_config.models_module = True
create_permissions(app_config, apps=apps, verbosity=0)
app_config.models_module = None
然后您的operations
如下:
operations = [
migrations.AlterModelOptions(
name='my_model',
options={'permissions': (('my_new_permissoin_code', 'Permission name'),)},
),
migrations.RunPython(create_permissions),
migrations.RunPython(assign_new_permission)
]
无论如何,我希望能有所帮助。抱歉,信息过多-过去我遇到过与您相同的问题,这让我退缩了几天。