Reputation: 3056
I have Django models, serializers and views:
from django.db import models
# Create your models here.
class Contract(models.Model):
contract_no = models.IntegerField(blank=False, unique=True)
customer = models.IntegerField(blank=False)
agent = models.IntegerField(blank=False)
agency = models.IntegerField(blank=False)
cont_date = models.DateField()
def __str__(self):
"""Return a human readable representation of the model instance."""
return "{}".format(self.contract_no)
class ContractOrder(models.Model):
order_no = models.IntegerField(blank=False, unique=True)
order_date = models.DateField()
contract = models.ForeignKey(Contract, on_delete=models.DO_NOTHING)
def __str__(self):
return self.order_no
class Meta:
ordering = ('order_no',)
from rest_framework import serializers
from .models import Contract
from .models import ContractOrder
class ContractSerializer(serializers.ModelSerializer):
"""Serializer to map the Model instance into JSON format."""
class Meta:
"""Meta class to map serializer's fields with the model fields."""
model = Contract
fields = ('contract_no', 'customer', 'agent', 'agency', 'cont_date')
#read_only_fields = ('date_created', 'date_modified')
class ContractOrderSerializer(serializers.ModelSerializer):
"""Serializer to map the Model instance into JSON format."""
class Meta:
"""Meta class to map serializer's fields with the model fields."""
model = ContractOrder
fields = ('order_no', 'order_date', 'contract')
#read_only_fields = ('date_created', 'date_modified')
from rest_framework import generics
from .serializers import ContractSerializer
from .models import Contract
from .serializers import ContractOrderSerializer
from .models import ContractOrder
class ContractCreateView(generics.ListCreateAPIView):
"""This class defines the create behavior of our rest api."""
queryset = Contract.objects.all()
serializer_class = ContractSerializer
def perform_create(self, serializer):
"""Save the post data when creating a new bucketlist."""
serializer.save()
class ContractOrderCreateView(generics.ListCreateAPIView):
"""This class defines the create behavior of our rest api."""
queryset = ContractOrder.objects.all()
serializer_class = ContractOrderSerializer
def perform_create(self, serializer):
"""Save the post data when creating a new bucketlist."""
serializer.save()
And the results /contracts and /contract_orders JSON messages are simple:
[{"contract_no":1,"customer":1,"agent":1,"agency":1,"cont_date":"2018-04-26"},{"contract_no":2,"customer":2,"agent":2,"agency":2,"cont_date":"2018-04-25"}]
[{"order_no":1,"order_date":"2018-04-26","contract":1}]
But I wish to have more expanded JSON messages, specifically:
Contract JSON entity should have array of ContractOrder entities (in my case contract 1 should have array with 1 entry)
ContractOrder JSON entity should have expanded contract entity - at present contract field (in JSON) contains only scalar value 1, but I would like to have full Contract entity.
Of course - there will be situations when the JSON graph should be expanded fully, when it should be contracted and then there will be situations when the expansion should be partial? Is it possible to achieve this in Django?
I have experience that in Java JPA/Hibernate/Spring it is possible to control the entity graph (in memory) and JSON view of the entity graph (in REST) using annotations @OneToMany
and @JsonView
(from com.fasterxml.jackson.annotation.JsonView
library) but how to achieve this in Django - both - in memory and in REST JSON messages?
Upvotes: 1
Views: 324
Reputation: 5347
Change your serializers as follows:
class SimpleContractOrderSerializer(serializers.ModelSerialiser): # Required; otherwise you get into a recursive loop.
class Meta:
"""Meta class to map serializer's fields with the model fields."""
model = ContractOrder
fields = ('order_no', 'order_date',)
class ContractSerializer(serializers.ModelSerializer):
"""Serializer to map the Model instance into JSON format."""
contract_order = SimpleContractOrderSerializer(source='contractorder', many=True, read_only=True)
class Meta:
"""Meta class to map serializer's fields with the model fields."""
model = Contract
fields = ('contract_no', 'customer', 'agent', 'agency', 'cont_date')
#read_only_fields = ('date_created', 'date_modified')
class ContractOrderSerializer(serializers.ModelSerializer):
"""Serializer to map the Model instance into JSON format."""
contract = ContractSerializer(read_only=True)
class Meta:
"""Meta class to map serializer's fields with the model fields."""
model = ContractOrder
fields = ('order_no', 'order_date', 'contract')
#read_only_fields = ('date_created', 'date_modified')
Read more here: http://www.django-rest-framework.org/api-guide/relations/#nested-relationships
Upvotes: 3