0

Hi I'm new to django rest framework and I'm trying to serialize 3 nested models. The relationships are: hotel_social_media_type has a one to many relationship to hotel_social_media and hotel has one to many relationship to hotel_social_media. Right now I can only serialized hotel to hotel_social_media but I can't serialize hotel_social_media_type.

Here's my serializers:

class SocialMediaTypeSerializer(serializers.ModelSerializer):
    """Serializes social media type"""

    class Meta:
        model = models.SocialMediaType
        fields = ('name', 'icon', 'url')


class HotelSocialMediaSerializer(serializers.ModelSerializer):
    """Serializes media files"""
    hotel_social_media_type = SocialMediaTypeSerializer(many=False, read_only=True)

    class Meta:
        model = models.HotelSocialMedia
        fields = ('url', 'hotel_social_media_type')


class HotelSerializer(serializers.ModelSerializer):
    """Serializes Restaurat, Bars, TouristInformation and Tourist Spots """

    hotel_images = HotelImageSerializer(many=True, read_only=True)
    hotel_social_media = HotelSocialMediaSerializer(many=True, read_only=True)

    class Meta:
        model = models.Hotel
        fields = ('id', 'name', 'hotel_images', 'hotel_social_media')

Models:

class Hotel(models.Model):
    """Database model for hotels"""
    name = models.CharField(max_length=50)

    def __str__(self):
        """Return the model as a string"""
        return self.name

class HotelImage(models.Model):
    """Image upload for hotel"""
    name = models.CharField(max_length=50)
    description = models.CharField(max_length=250)
    path = models.ImageField(upload_to='images/')
    created_on = models.DateTimeField(auto_now_add=True)
    is_active = models.BooleanField(default=True)

    hotel = models.ForeignKey(Hotel, related_name='hotel_images', on_delete=models.CASCADE, null=True)

    def __str__(self):
        """Return the model as a string"""
        return self.name

class SocialMediaType(models.Model):
    """Social Media Type eg: fb, twitter"""
    name = models.CharField(max_length=50)
    icon = models.ImageField(upload_to='images/')
    url = models.CharField(max_length=50)

    def __str__(self):
        """Return the model as a string"""
        return self.name

class HotelSocialMedia(models.Model):
    """Social Media"""

    hotel = models.ForeignKey(Hotel, related_name='hotel_social_media', on_delete=models.CASCADE, null=True)
    type = models.ForeignKey(SocialMediaType, related_name='hotel_social_media_type', on_delete=models.CASCADE, null=True)

    name = models.CharField(max_length=50)
    url = models.CharField(max_length=50)

    def __str__(self):
        """Return the model as a string"""
        return self.name

Current result is:

{
  "id": 1,
  "name": "Alta Vista",
  "hotel_images": [
    {
      "id": 1,
      "name": "Alta Vista",
      "path": "http://127.0.0.1:8000/media/images/hotel-1.jpg"
    }
  ],
  "hotel_social_media": [
    {
      "url": "https://www.facebook.com/abscbnNEWS"
    }
  ]
}

What I want is:

{
  "id": 1,
  "name": "Alta Vista",
  "hotel_images": [
    {
      "id": 1,
      "name": "Alta Vista",
      "path": "http://127.0.0.1:8000/media/images/hotel-1.jpg"
    }
  ],
  "hotel_social_media": [
    {
      "url": "https://www.facebook.com/abscbnNEWS",
      "hotel_social_media_type": {
        "name": "Facebook",
        "icon": "http://127.0.0.1:8000/media/images/fb-1.jpg"
      }
    }
  ]
}



`hotel_social_media` must also display `hotel_social_media_type`
2
  • Could you show your models? Commented Mar 4, 2020 at 13:59
  • @kamilyrb I updated my post. thanks Commented Mar 4, 2020 at 14:14

1 Answer 1

1

Based on your model, you must use type keyword instead of hotel_social_media_type in your HotelSocialMediaSerializer. Because your HotelSocialMedia has type field for relation with HotelSocialMediaType.To change keyword can solve your problem.

class HotelSocialMediaSerializer(serializers.ModelSerializer):
   """Serializes media files"""
    type = SocialMediaTypeSerializer(many=False, read_only=True)

    class Meta:
        model = models.HotelSocialMedia
        fields = ('url', 'type')

If you want to use hotel_social_media_type keyword, you can use SerializerMethodField like that:

class HotelSocialMediaSerializer(serializers.ModelSerializer):
   """Serializes media files"""
    hotel_social_media_type = serializers.SerializerMethodField()

    class Meta:
        model = models.HotelSocialMedia
        fields = ('url', 'hotel_social_media_type')

    def get_hotel_social_media_type(self.obj):
        serializer = SocialMediaTypeSerializer(obj.type)
        return serializer.data
Sign up to request clarification or add additional context in comments.

Comments

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.