4

I'm quite new to Django Rest Framework. I couldn't find on the docs something that would allow me to serialize my models according to the JSON API standards (jsonapi.org).

Let's suppose I have the following models.

class Person(models.Model):
    name = models.CharField(max_length=200)


class Car(models.Model):
    owner = models.ForeignKey(Person)
    brand =  
    model = models.CharField(max_length=200)
    plate = models.CharField(max_length=200)

I would like to serialize it in a way that it would provide me with the following output:

{
    "data":[
        {
            "type": "Person",
            "id": 1,
            "attributes": {
                "name": "John",
            },
            "relationships": {
                "cars": [
                    {
                        "data": {
                            "type": "Car",
                            "id": 1,
                            "attributes": {
                                "brand": "Bugatti",
                                "model": "Veyron",
                                "plate": "PAD-305",
                            },
                        },
                    },
                    {
                        "data": {
                            "type": "Car",
                            "id": 2,
                            "attributes": {
                                "brand": "Bugatti",
                                "model": "Chiron",
                                "plate": "MAD-054",
                            },
                        },
                    },
                ],
            },
        },

        {
            "type": "Person",
            "id": 2,
            "attributes": {
                "name": "Charllot",
            },
            "relationships": {
                "cars": [
                    {
                        "data": {
                            "type": "Car",
                            "id": 3,
                            "attributes": {
                                "brand": "Volkswagen",
                                "model": "Passat CC",
                                "plate": "OIJ-210",
                            },
                        },
                    },
                    {
                        "data": {
                            "type": "Car",
                            "id": 4,
                            "attributes": {
                                "brand": "Audi",
                                "model": "A6",
                                "plate": "NAD-004",
                            },
                        },
                    },
                ],
            },
        }
    ],

    "meta":{
        "backend_runtime": "300ms", // processed at the view
    }
}
Mauricio
  • 2,552
  • 2
  • 29
  • 43

2 Answers2

2

You can create your serializer to return the data any way you want. For example, if you want to ignore the exact model structure you can do the following

from rest_framework import serializers

class PersonSerializer(serializers.Serializer):
    """
    Person/Car serializer
    """
    id = serializers.IntegerField(read_only=True)
    name = serializers.CharField()
    attributes = serializers.SerializerMethodField()

    def get_attributes(self, obj):
        return {"name": obj.name}

If you want a serializer structure that is closer to your models, you can relate model serializers using the following approach:

from rest_framework import serializers

class CarSerializer(serializers.ModelSerializer):
    """Serializes car object"""    
    class Meta:
        model = Car
        fields = ('id', 'brand',)


class PersonSerializer(serializers.ModelSerializer):
    """Serializes person and car relationship"""
    car = CarSerializer(read_only=True) 

    class Meta:
        model = Person
        fields = ('id', 'name', 'car',)

In both cases, you would be passing a queryset to the serializer that contains these fields (and in the nested model serializer, the existing relationships).

djq
  • 14,810
  • 45
  • 122
  • 157
1

Parsers and Renderers are the component that allows you to alter the serializer's response. Note that there's already a third party that implements jsonapi with Django REST framework: https://github.com/django-json-api/django-rest-framework-json-api

Dont forget to look at the Django REST framework third party page if you're looking for something.

glaucon
  • 8,112
  • 9
  • 41
  • 63
Linovia
  • 19,812
  • 4
  • 47
  • 48