【问题标题】:Django pytest database access for data migration用于数据迁移的 Django pytest 数据库访问
【发布时间】:2016-10-08 09:50:04
【问题描述】:

我正在使用Django (1.9.6)pytest (2.9.2)pytest-django (2.9.1)

我有一个如下所示的数据迁移:

# -*- 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 的测试都会在get 迁移操作中引发__fake__.DoesNotExist: Permission matching query does not exist.

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

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

【问题讨论】:

标签: python django pytest pytest-django


【解决方案1】:

感谢@Håken Lid 和他提供的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 应用迁移作为依赖项。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-01
    • 2018-03-04
    • 2014-01-13
    • 1970-01-01
    • 1970-01-01
    • 2014-07-30
    • 1970-01-01
    • 2017-08-19
    相关资源
    最近更新 更多