Newtt
Newtt

Reputation: 6190

Serialize related models in Django Rest Framework

I have django models that are simplified as:

class Client(models.Model):
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name


class ClientDetail(models.Model):
    client = models.ForeignKey(Client, on_delete=models.CASCADE)
    business_format = models.CharField(max_length=255)


    def __str__(self):
        return "Details for {}".format(self.client.name)


class ClientAssignment(models.Model):
    client = models.ForeignKey(Client, on_delete=models.CASCADE)
    assignment = models.ForeignKey(Assignment, on_delete=models.CASCADE)


    def __str__(self):
        return "Assignment: {} for Client: {}".format(self.assignment.name, self.client.name)

class Assignment(models.Model):
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name

I am using django-rest-framework and would like to create a view where I can provide client_id and receive a serialized object that contains all 3 related models. I tried using PrimaryKeyRelatedField as follows but I'm not sure if I'm using this correctly.

class CompleteClientObject(ModelSerializer):
    assignment = PrimaryKeyRelatedField(many=True, queryset=ClientAssignment.objects)
    detail = PrimaryKeyRelatedField(many=True, queryset=ClientDetail.objects)
    client = PrimaryKeyRelatedField(queryset=Client)

    class Meta:
        model = Client
        fields = ("id", "name", "detail", "assignment",)

How can I achieve this using serializers?

Upvotes: 4

Views: 2116

Answers (1)

A. J. Parr
A. J. Parr

Reputation: 8026

In your serializer fields you can use the source argument to specify a field on the model. If you're trying to access the reverse relation from the Client model you should be using the MODELNAME_set field on as your source. This field is added to the other end of a ForeignKey by Django. I.e.

assignment = PrimaryKeyRelatedField(
    source='clientassignment_set',
    many=True,
    read_only=True,
)

Note that with read_only=True you don't need to specify a queryset either.

Your other choice would be to specify a related_name field on your ForeignKey's which overrides the MODELNAME_set auto-generated fields, and set these to "assignment" and "detail".

Upvotes: 5

Related Questions