Python Django Отображение вложенных объектов - PullRequest
0 голосов
/ 04 марта 2020

Привет, я новичок в django фреймворке отдыха и пытаюсь сериализовать 3 вложенные модели. Отношения: hotel_social_media_type имеет отношение один ко многим с hotel_social_media, а hotel имеет отношение один ко многим с hotel_social_media. Прямо сейчас я могу только сериализовать hotel до hotel_social_media, но не могу сериализовать hotel_social_media_type.

Вот мои сериализаторы:

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')

Модели:

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

Текущий результат:

{
  "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"
    }
  ]
}

То, что я хочу:

{
  "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`

1 Ответ

1 голос
/ 04 марта 2020

В зависимости от вашей модели, вы должны использовать ключевое слово type вместо hotel_social_media_type в вашем HotelSocialMediaSerializer. Поскольку ваше HotelSocialMedia имеет type поле для связи с HotelSocialMediaType. Изменение ключевого слова может решить вашу проблему.

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

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

Если вы хотите использовать ключевое слово hotel_social_media_typ e, вы можете использовать SerializerMethodField вот так:

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