'Django defining a json type on model makes jsonb instead of json

I am using the JSONField for my Django model for JSON type but in the background, it makes my attributes column type JSONB which I don't want to do here because it breaks my exact order of JSON'S internal field that I pushed from my frontend app. You can see the order of fields is not my exact value. To store it as it is, I need to use JSON instead of jsonb. So my question is how to do that?

What I pushed:

{
  "type": "array",
  "title": "action_right",
  "additionalProperties": true,
  "items": {
    "type": "object",
    "required": [
      "label",
      "url"
    ],
    "properties": {
      "label": {
        "type": "string",
        "custom_type": "string",
        "title": "label",
        "default": ""
      },
      "url": {
        "type": "string",
        "custom_type": "string",
        "title": "url",
        "default": ""
      }
    }
  }
}

What is stored:

{
  "type": "array",
  "items": {
    "type": "object",
    "required": [
      "label",
      "url"
    ],
    "properties": {
      "url": {
        "type": "string",
        "title": "url",
        "default": "",
        "custom_type": "string"
      },
      "label": {
        "type": "string",
        "title": "label",
        "default": "",
        "custom_type": "string"
      }
    }
  },
  "title": "action_right",
  "additionalProperties": true
}

Code snippets:

class Component(models.Model):
    name = models.CharField(max_length=200, unique=True)
    attributes = models.JSONField(default=dict, help_text='Component attributes in JSONSchema')

Notes:

PostgreSQL has two native JSON based data types: json and jsonb. The main difference between them is how they are stored and how they can be queried. PostgreSQL’s json field is stored as the original string representation of the JSON and must be decoded on the fly when queried based on keys. The jsonb field is stored based on the actual structure of the JSON which allows indexing. The trade-off is a small additional cost on writing to the jsonb field. JSONField uses jsonb.



Solution 1:[1]

Try this (may need to be tweaked):

import json

class RawJSONField(models.JSONField):
    def db_type(self, connection):
        return 'text'

    def get_prep_value(self, value):
        return json.dumps(value)

    def from_db_value(self, value, expression, connection):
        if value is None:
            return value
        return json.loads(value)

in some model:

class Calculation(models.Model):
    calc_result = RawJSONField(_("Calc result data"), default = dict)

other variant:

from django.db import models
import json

class RawJSONField(models.TextField):
    def get_prep_value(self, value):
        return json.dumps(value)

    def from_db_value(self, value, expression, connection):
        if value is None:
            return value
        return json.loads(value)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1