Skip to content

Instantly share code, notes, and snippets.

@Vibhu-Agarwal
Last active March 7, 2024 00:28
Show Gist options
  • Save Vibhu-Agarwal/8f71bbef7072f1deea05c75abfb3c941 to your computer and use it in GitHub Desktop.
Save Vibhu-Agarwal/8f71bbef7072f1deea05c75abfb3c941 to your computer and use it in GitHub Desktop.
Example Describing How to Serialize Multiple Models through One Serializer (Case of Foreign Keys) | Django Rest Framework
from django.db import models
class ModelA(models.Model):
fieldA1 = models.CharField(max_length=100, unique=True)
fieldA2 = models.TextField(validators=[URLValidator()], blank=True, null=True)
fieldA3 = models.CharField(max_length=100, unique=True, null=True, blank=True)
field4 = models.BooleanField(default=True)
class ModelB(models.Model):
model_a_field = models.ForeignKey('ModelA', on_delete=models.CASCADE, related_name="model_b_field")
fieldB1 = models.CharField(max_length=70, null=True, blank=True)
fieldB2 = models.PositiveIntegerField(default=0)
fieldB3 = models.BooleanField(default=False)
field4 = models.BooleanField(default=True)
from rest_framework import serializers
class ModelACreateSerializer(serializers.ModelSerializer):
"""
Serializer to Add ModelA together with ModelB
"""
class ModelBTempSerializer(serializers.ModelSerializer):
class Meta:
model = ModelB
# 'model_a_field' is a FK which will be assigned after creation of 'ModelA' model entry
# First entry of ModelB will have (default) fieldB3 value as True, rest as False
# 'field4' will be derived from its counterpart from the 'Product' model attribute
exclude = ['model_a_field', 'fieldB3', 'field4']
model_b = ModelBTempSerializer()
class Meta:
model = ModelA
fields = '__all__'
def create(self, validated_data):
model_b_data = validated_data.pop('model_b')
model_a_instance = ModelA.objects.create(**validated_data)
ModelB.objects.create(model_a_field=model_a_instance,
fieldB3=True,
field4=model_a_instance.field4,
**model_b_data)
return model_a_instance
from rest_framework import generics
class ModelACreateAPIView(generics.CreateAPIView):
"""
Create a new ModelA entry with ModelB entry
"""
queryset = ModelA.objects.all()
serializer_class = ModelACreateSerializer
@Prajakta-Ghorpade
Copy link

This is a super helpful and easy to understand example since its very well written! Thank you so much!

@HarshSonawane
Copy link

Hey what would you do if you want something like below?

{
"fieldA1": "",
"fieldA2": "",
"fieldA3": "",
"field4": "",
"fieldB1": "",
"fieldB2": "",
"fieldB3": "",
"field4": "",
}

I don't want to do it with methods.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment