56

I'm trying to return a HttpResponse from Django Rest Framework including data from 2 linked models. The models are:

class Wine(models.Model):

    color = models.CharField(max_length=100, blank=True)
    country = models.CharField(max_length=100, blank=True)
    region = models.CharField(max_length=100, blank=True)
    appellation = models.CharField(max_length=100, blank=True)

class Bottle(models.Model):

    wine = models.ForeignKey(Wine, null=False)
    user = models.ForeignKey(User, null=False, related_name='bottles')

I'd like to have a serializer for the Bottle model which includes information from the related Wine.

I tried:

class BottleSerializer(serializers.HyperlinkedModelSerializer):
    wine = serializers.RelatedField(source='wine')

    class Meta:
        model = Bottle
        fields = ('url', 'wine.color', 'wine.country', 'user', 'date_rated', 'rating', 'comment', 'get_more')

which doesn't work.

Any ideas how I could do that?

Thanks :)

bpipat
  • 3,700
  • 4
  • 20
  • 22
  • Thanks for this, I'm almost there. What @tom-christie explains works to get the object itself but I'm unable to get all the fields from the Wine object.. – bpipat Dec 17 '13 at 13:19
  • Try `source='*'` as `RelatedField` argument. – mariodev Dec 17 '13 at 14:02
  • I still get the unicode name in the result of the query. And trying wine.color in the fields doesn't work What does source='*' change? – bpipat Dec 17 '13 at 14:07

2 Answers2

64

Simple as that, adding the WineSerializer as a field solved it.

class BottleSerializer(serializers.HyperlinkedModelSerializer):
    wine = WineSerializer(source='wine')

    class Meta:
        model = Bottle
        fields = ('url', 'wine', 'user', 'date_rated', 'rating', 'comment', 'get_more')

with:

class WineSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = Wine
        fields = ('id', 'url', 'color', 'country', 'region', 'appellation')

Thanks for the help @mariodev :)

bpipat
  • 3,700
  • 4
  • 20
  • 22
  • Glad you sort that out. Can you also please explain what `WineSerializer` class stands for, so we have a clear answer.. – mariodev Dec 17 '13 at 14:25
  • 1
    I've done this but I'm getting the fallowing error `HyperlinkedRelatedField requires the request in the serializer context. Add context={'request': request}` when instantiating the serializer.`. What am I doing wrong? – arturataide Aug 07 '15 at 21:06
  • got error like this: AssertionError(u"`HyperlinkedIdentityField` requires the request in the serializer context. Add `context={'request': request}` when instantiating the serializer.",) is not JSON serializable. – Mahabubur Rahaman Melon Jun 04 '16 at 17:58
  • You shouldn't need the `source='wine'` argument since it's the same as the name. In fact I'm surprised if you aren't getting a runtime error for that. Instead you can add other args like `(many=False, read_only=True)` – shanemgrey Sep 15 '16 at 20:32
  • To anybody with the same problem - you don't have to use `HyperlinkedModelSerializer`, `ModelSerializer` will do just fine. – roboslone Dec 26 '16 at 04:21
  • 9
    This will result in an embedded object under the `wine` property. Is there a way to get specific fields from the related `Wine` model embedded _directly_ in the top-level object? – mgalgs May 15 '17 at 23:27
22

If you want to get specific field you can use Serializer Fields

https://www.django-rest-framework.org/api-guide/fields/

    class BottleSerializer(serializers.HyperlinkedModelSerializer):
        winecolor = serializers.CharField(read_only=True, source="wine.color")

        class Meta:
            model = Bottle
            fields = ('url', 'winecolor', 'user', 'date_rated', 'rating', 'comment', 'get_more')
Ryan Jeric
  • 380
  • 2
  • 9
  • 3
    For anyone else who spent way too long trying to figure out how this links to the related serializer, the source="wine.color" follows the foreign key relationship defined in the model. In this case, the foreign key was named 'wine', and the related field is 'color'. – Rishi Latchmepersad Apr 21 '21 at 18:02