Search code examples
django-rest-frameworkdjango-serializer

Get the related model entries with a single GET request to the master model in DRF


I've one master model and six other models which are foreign key related to my master.

My models:

#MASTER TABLE
class UserDetails(models.Model):
    user_id = models.UUIDField(primary_key=True,default=uuid.uuid4,editable=False)
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)

#RELATED TABLES
class EducationProfile(models.Model):
    degree_level = models.CharField(max_length=100, null=True, blank=True)
    degree = models.CharField(max_length=100, null=True, blank=True)
    start_date = models.DateField(null=True, blank=True)
    completion_date = models.DateField(null=True, blank=True)
    user = models.ForeignKey(UserDetails, related_name='education')

class AwardsRecognitions(models.Model):
    award_name = models.CharField(max_length=100, null=True, blank=True)
    awarded_by = models.CharField(max_length=100, null=True, blank=True)
    award_date = models.DateField(null=True, blank=True)
    user = models.ForeignKey(UserDetails, related_name='awards')

I'm trying to fetch the info of all the related models with me GET request to the UserDetails model. I've tried using PrimaryKeyRelatedField in the UserDetailsSerializer but that is not giving me the expected output. The result is having only the related entry's id in the nested fields.

My Serializers:

class UserDetailsSerializer(serializers.ModelSerializer):
    education = serializers.PrimaryKeyRelatedField(read_only=True, many=True)
    awards = serializers.PrimaryKeyRelatedField(read_only = True, many = True)

    class Meta:
        model = UserDetails
        fields = '__all__'

class EducationProfileSerializer(serializers.ModelSerializer):

    class Meta:
        model = EducationProfile
        fields = '__all__'

class AwardsRecognitionsSerializer(serializers.ModelSerializer):

    class Meta:
        model = AwardsRecognitions
        fields = '__all__'

Expected Result:

GET Request format - <<UserDetails_model_endpoint>>/<<user_id_primary_key>>/

Response format -

{"user_id" : <<user_id>>,
 "first_name" : "foo",
 "last_name" : "bar",
 "education":[{"id":5,
               "degree_level": "xxxx",
               "degree":"xxxx",
               "start_date":"xxxx",
               "completion_date":"xxxx"},
              {"id":7,
               "degree_level": "yyyy",
               "degree":"yyyy",
               "start_date":"yyyy",
               "completion_date":"yyyy"}],
 "awards":[{"id":3,
            "award_name":"nnnn",
            "awarded_by":"nnnn",
            "awarded_date":"nnnn"},
           {"id":7,
            "award_name":"mmm",
            "awarded_by":"mmmm",
            "award_date":"mmmm"}]

Kindly point me in the correct direction to achieve this, any idea is appreciated. TIA


Solution

  • Include serializers for the models you have created for related models instead of the primary key related field. PrimaryKeyRelatedField will give you only the primary key in the JSON as the name suggests.

    class UserDetailsSerializer(serializers.ModelSerializer):
        education = EducationProfileSerializer(many=True, read_only=True)
        awards = AwardsRecognitionsSerializer(many=True, read_only=True)
    
        class Meta:
            model = UserDetails
            fields = '__all__'
    

    For more details checkout https://www.django-rest-framework.org/api-guide/relations/#nested-relationships