Django的pytest数据迁移

Django的pytest数据迁移

问题描述:

我使用Django (1.9.6)pytest (2.9.2)pytest-django (2.9.1)Django的pytest数据迁移

数据库访问我有一个数据迁移,看起来像这样:

# -*- coding: utf-8 -*- 
# Generated by Django 1.9.6 on 2016-06-07 09:56 
from __future__ import unicode_literals 

from django.db import migrations 


def create_groups(apps, schema_editor): 
    Group = apps.get_model('auth', 'group') 
    Permission = apps.get_model('auth', 'permission') 

    group1 = Group.objects.create(name='grou1') 
    group1_permissions = Permission.objects.filter(codename__in=[ 
     'add_app1_model', 
     'add_app2_model', 
     'custom_permission_app1_model' 
    ]) 
    group1.permissions.add(*list(group1_permissions)) 

    group2 = Group.objects.create(name='group2') 
    group2_permissions = Permission.objects.get(
     codename='custom_permission_app2_model'  
    ) 
    group2.permissions.add(*list(group2_permissions)) 


class Migration(migrations.Migration): 

    dependencies = [ 
     ('app1', '0001'), 
     ('app2', '0001') 
    ] 

    operations = [ 
     migrations.RunPython(create_groups) 
    ] 

当我执行py.test --create-db所有的测试中标记用pytest.mark.django_db正在筹集__fake__.DoesNotExist: Permission matching query does not exist.get的迁移操作。

调试迁移我发现create操作正常,但filter操作总是返回空白,我的测试数据库创建了组,但没有权限与任何组关联。

我不知道我是否做错了什么?我所做的临时修复是将get更改为filter,这使迁移正常执行。在测试中,我有一个固定装置可以为用户分配所需的权限。因为我所有的代码都是根据权限进行检查的,而不是如果用户属于一个组,我所有的测试都会通过。

+0

在这个django问题跟踪器讨论中,如何解决这个问题有一些建议。 https://code.djangoproject.com/ticket/23422 –

由于@HåkenLid和他提供的Django issue,我找到了解决方案。问题在于Django在所有迁移完成时创建接收发出信号的ContentTypes。这就是为什么它没有找到权限,但它让我创建组。

为了解决这个问题,我们必须在数据迁移中手动发送信号。

# -*- coding: utf-8 -*- 
# Generated by Django 1.9.6 on 2016-06-07 09:56 
from __future__ import unicode_literals 

from django.core.management.sql import emit_post_migrate_signal 
from django.db import migrations 


def create_groups(apps, schema_editor): 
    # Send the signal to create the permissions 
    db_alias = schema_editor.connection.alias 
    try: 
     # Django 1.9 
     emit_post_migrate_signal(2, False, db_alias) 
    except TypeError: 
     # Django < 1.9 
     try: 
      # Django 1.8 
      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') 

    group1 = Group.objects.create(name='grou1') 
    group1_permissions = Permission.objects.filter(codename__in=[ 
     'add_app1_model', 
     'add_app2_model', 
     'custom_permission_app1_model' 
    ]) 
    group1.permissions.add(*list(group1_permissions)) 

    group2 = Group.objects.create(name='group2') 
    group2_permissions = Permission.objects.get(
     codename='custom_permission_app2_model'  
    ) 
    group2.permissions.add(*list(group2_permissions)) 


class Migration(migrations.Migration): 

    dependencies = [ 
     ('app1', '0001'), 
     ('app2', '0001'), 
     ('contenttypes', '__latest__'), 
     ('sites', '__latest__') 
    ] 

    operations = [ 
     migrations.RunPython(create_groups) 
    ] 

在剪断我们访问权限之前发送的信号,我们有最新的contenttypessites应用程序迁移的依赖关系。