pythondjangopostgresqldjango-modelsdjango-rest-framework

Using Django JSONField in model


I am creating REST API's.

django==3.2.2
djangorestframework==3.12.4
psycopg2==2.8.6

I am new to Django, python. I looking for a way to use the JSON field in the Django model. My model looks like below -

class Question(BaseModel):
.... other code...
    attributes = models.JSONField()

Now I want the attributes to be a JSON, like below

{
    "index": 0,
    "guid": "95161b18-75a8-46bf-bb1f-6d1e16e3d60b",
    "isActive": false,
    "latitude": -25.191983,
    "longitude": -123.930584,
    "tags": [
      "esse",
      "sunt",
      "quis"
    ],
    "friends": [
      {
        "id": 0,
        "name": "Contreras Weeks"
      },
      {
        "id": 1,
        "name": "Dawn Lott"
      }
    ]
}

Should I create a new model, but creating a new model will make it add to migrations which I do not want.

  1. How to create a model for the above?
  2. How can I use the default validation provided by Django ORM on it?

Solution

  • I figured out - we can use Pydantic or schema for Django. They also offer validation. I preferred Pydantic.

    EDIT

    Pydantic example

    Schema:

    from typing import List
    from pydantic import (
        BaseModel,
        StrictBool,
        StrictInt,
        StrictStr,
    )
    
    class Foo(BaseModel):
        count: int
        size: float = None
    
    
    class Bar(BaseModel):
        apple = 'x'
        banana = 'y'
    
    class AttributesSchema(BaseModel):
        point: StrictInt
        value: StrictStr
        foo: Foo
        bars: List[Bar]
    

    will return JSON like:

    {
        'point': 2,
        'value': 'Any string'
        'foo': {'count': 4, 'size': None},
        'bars': [
            {'apple': 'x1', 'banana': 'y'},
            {'apple': 'x2', 'banana': 'y'},
        ],
    }
    

    Validation

    Add this to your serializer:

    schema = AttributesSchema
    try:
        errors = schema.validate(data['attributes'])
    except Exception as errors:
        raise serializers.ValidationError(errors)
    

    Refer to Pydantic documentation, it has everything we need.