Wootiae
Wootiae

Reputation: 848

How to join models in django serializers?

I'm trying to join two models, but I got the wrong result. How to do it right?

My models:

class MoocherPage(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=False)
    name = models.CharField(max_length=48, unique=True, blank=False, null=False)
    bio = models.TextField(blank=False, null=False)


class MoocherResource(models.Model):
    url = models.URLField(blank=False, null=False)
    moocher = models.ForeignKey(MoocherPage, on_delete=models.CASCADE)

And serializers:

class MoocherResourceSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        URL_FIELD_NAME = 'url'
        model = MoocherResource
        fields = ('url', )


class MoocherPageSerializer(serializers.ModelSerializer):
    resources = MoocherResourceSerializer(many=True, read_only=True)

    class Meta:
        model = MoocherPage
        fields = ('name', 'bio', 'resources')
        depth = 1

I expected

{
    "name": "KissofLove",
    "bio": "I'm the kiss of love and I collect money for all lovers of the world.",
    "resources": ["https://stackoverflow.com/users/KissofLove"]
}

But the resources was not included.


When I change read_only=True to False in the nested serializer an error appears. AttributeError: Original exception text was: 'MoocherPage' object has no attribute 'resources'.

Upvotes: 0

Views: 125

Answers (1)

czarss
czarss

Reputation: 121

Your models

class MoocherPage(models.Model):
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=False)
    name = models.CharField(max_length=48, unique=True, blank=False, null=False)
    bio = models.TextField(blank=False, null=False)


class MoocherResource(models.Model):
    url = models.URLField(blank=False, null=False)
    moocher = models.ForeignKey(MoocherPage, on_delete=models.CASCADE)

and your serializers,

from rest_framework.serializers import *

class ResourceListingField(RelatedField):
    def to_representation(self, value):
        return value.url


class MoocherPageSerializer(ModelSerializer):
    resources = ResourceListingField(many=True, source='moocherresource_set', read_only=True)

    class Meta:
        model = MoocherPage
        fields = ['name', 'bio', 'resources']

This returns the desired

{
"name": "KissOfLove",
"bio": "I'm the kiss of love and I collect money for all lovers of the world.",
"resources": ["https://stackoverflow.com/users/KissofLove"]
}

response.

Check out Custom relational fields

Upvotes: 1

Related Questions