4

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?

1 Answer 1

5

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".

Sign up to request clarification or add additional context in comments.

5 Comments

What would my Meta.model property be? Client?
That's correct, your Metal.model would still be Client.
This gives me a 'Client' object has no attribute 'assignment' error. I assume this is since the base Client model doesn't have a assignment field
That is why you should be using the source attribute on your assignment serializer field to specify that the assign serializer field should use the clientassignment_set field on the model
This gives me a Object of type 'RelatedManager' is not JSON serializable error which I'm not sure how to solve.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.