Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test postgresql specific feature such as JsonField in Django?

I would like to use Postgresql specific JSONField in Django, however, I have not found a way to test with sqlite environment.

Any tip for elegant way?

like image 239
Jun Avatar asked Oct 13 '16 07:10

Jun


People also ask

What is JSONField Django?

One of the cool features introduced in Django 3.1 was the JSONField. It allows you to store semi-structured data alongside other information in the database. Adopting new things can be scary for an existing project, though, because you have to migrate to it.

What is JSONField in Python?

jsonfield is a reusable model field that allows you to store validated JSON, automatically handling serialization to and from the database. To use, add jsonfield. JSONField to one of your models. Note: django. contrib.

What is Django contrib Postgres?

contrib. postgres. PostgreSQL has a number of features which are not shared by the other databases Django supports. This optional module contains model fields and form fields for a number of PostgreSQL specific data types.


1 Answers

If you are using Django3.1, The JSON1 extension can be used. If you are running a Django version less than 3.1, below code may help:

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

Import the JSONField from this file in your project and it will adjust itself for both SQLite and PostgreSQL.

like image 63
Utkarsh Sharma Avatar answered Sep 28 '22 05:09

Utkarsh Sharma