【问题标题】:How to test postgresql specific feature such as JsonField in Django?如何在 Django 中测试诸如 JsonField 之类的 postgresql 特定功能?
【发布时间】:2016-10-13 07:04:07
【问题描述】:

我想在 Django 中使用 Postgresql 特定的 JSONField,但是,我还没有找到使用 sqlite 环境进行测试的方法。

有什么优雅的方法吗?

【问题讨论】:

  • 测试JsonField是什么意思?
  • 如果您使用 Postgres 特定的功能,那么显然您还需要针对 Postgres 运行测试。
  • @SardorbekImomaliev 如果我定义 JsonField,则不会运行基于 sqlite 的测试,因为 sqlite 不支持 JsonField,但我仍想运行集成测试。
  • @DanielRoseman 我想避免在本地使用 postgresql 进行测试,我更喜欢使用 sqlite 来加快速度。这就是为什么我在这里发布以听取一些更好的解决方案,而不是使用 postgresql 运行。也许动态地将 JsonField 更改为纯文本或其他内容。
  • 好吧,我认为他并不能真正测试 JsonField - 但他的模型包括 JsonField,仅此一项就是一个问题。因此,如果您不关心拥有完全相同的测试环境,那么您唯一的选择就是动态地将其替换为对您的测试来说足够好的东西。

标签: django testing django-jsonfield


【解决方案1】:

如果您使用的是 Django3.1,则可以使用 JSON1 扩展。如果您运行的 Django 版本低于 3.1,下面的代码可能会有所帮助:

import json

from django.conf import settings
from django.contrib.postgres.fields import (
    JSONField as DjangoJSONField,
    ArrayField as DjangoArrayField,
)
from django.db.models import Field


class JSONField(DjangoJSONField):
    pass


class ArrayField(DjangoArrayField):
    pass


if 'sqlite' in settings.DATABASES['default']['ENGINE']:
    class JSONField(Field):
        def db_type(self, connection):
            return 'text'

        def from_db_value(self, value, expression, connection):
            if value is not None:
                return self.to_python(value)
            return value

        def to_python(self, value):
            if value is not None:
                try:
                    return json.loads(value)
                except (TypeError, ValueError):
                    return value
            return value

        def get_prep_value(self, value):
            if value is not None:
                return str(json.dumps(value))
            return value

        def value_to_string(self, obj):
            return self.value_from_object(obj)


    class ArrayField(JSONField):
        def __init__(self, base_field, size=None, **kwargs):
            """Care for DjanroArrayField's kwargs."""
            self.base_field = base_field
            self.size = size
            super().__init__(**kwargs)

        def deconstruct(self):
            """Need to create migrations properly."""
            name, path, args, kwargs = super().deconstruct()
            kwargs.update({
                'base_field': self.base_field.clone(),
                'size': self.size,
            })
            return name, path, args, kwargs

在您的项目中从此文件中导入 JSONField,它会针对 SQLite 和 PostgreSQL 进行自我调整。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-06
    • 2016-06-15
    • 1970-01-01
    • 2019-07-16
    • 1970-01-01
    • 2020-05-26
    • 1970-01-01
    相关资源
    最近更新 更多