#python #django #api #django-rest-framework
#python #django #API #django-rest-framework
Вопрос:
Привет всем, работая над Rest API в течение нескольких недель, я узнал о сериализаторах и вложенных сериализаторах. Я застрял на захвате полей из двух моделей, возможно ли это сделать в сериализаторе. Вот мой код.
class Slider(BaseModel):
page = models.ForeignKey(Page, on_delete=models.CASCADE)
section = models.CharField(
max_length=20,
validators=[validators.validate_section_name],
)
tag = models.CharField(
max_length=20,
validators=[validators.validate_tag_name],
)
class Meta:
default_permissions = ()
verbose_name = 'Slider'
verbose_name_plural = 'Sliders'
def __str__(self):
return self.section
следующая модель, которую я хочу объединить в сериализаторе, это
class SliderImage(BaseModel):
image = models.ImageField(
upload_to=upload_slider_image_to,
validators=[],
null=True, blank=True
)
slider = models.ForeignKey(Slider,
on_delete=models.CASCADE,
related_name='slider_image',
)
class Meta:
default_permissions = ()
verbose_name = 'Slider Image'
verbose_name_plural = 'Slider Images'
теперь есть ли какой-нибудь выход, чтобы я мог получить сериализаторы таким образом?
ожидаемый сериализатор выглядит как
"sliders": [
{
"images": [
"http://34.202.219.142:8000/media/promotion/slider/slider_56cc1829-aa78-40e3-9163-2c7297358de0.png",
"http://34.202.219.142:8000/media/promotion/slider/slider_4ea6d488-a1f6-4a0a-b522-ae0285e482df.png",
"http://34.202.219.142:8000/media/promotion/slider/slider_29862eb0-7a2a-4cc4-90b0-3ec5de510d75.png"
],
"section": "bus company",
"tag": "hot-deals"
},
Я пробовал это в сериализаторах
class SliderSerializers(serializers.ModelSerializer):
class Meta:
model = Slider
fields = '__all__'
class ListSliderSerializer(SliderSerializers):
class Meta(SliderSerializers.Meta):
fields = (
'section',
'tag',
)
class GetHomePagePromotionSerializer(serializers.Serializer):
sliders = ListSliderSerializer(many=True, read_only=True)
Я сериализую следующим образом в usecases.py и views.py как
#usecases
class GetHomePagePromotionUseCase(BaseUseCase):
def execute(self):
self._factory()
return self._home_page_promotion
def _factory(self):
self._home_page_promotion = {
'sliders': self.list_home_sliders(),
}
def list_home_sliders(self):
return SliderImage.objects.all()
#views.py
class GetHomePagePromotionView(generics.RetrieveAPIView):
"""
Use this end-point to get promotion items for the home page
"""
serializer_class = GetHomePagePromotionSerializer
def get_object(self):
return GetHomePagePromotionUseCase().execute()
Я новичок, надеюсь, я прояснил свой вопрос.
Комментарии:
1. Добавьте свой класс сериализатора. Кроме того, добавьте текущий результат и ожидаемый результат
Ответ №1:
Использовать serializers.SerializerMethodField
как
class ListSliderSerializer(SliderSerializers):
images = serializers.SerializerMethodField()
def get_images(self, instance):
return [slider_image.image.url for slider_image in instance.slider_image.all()]
class Meta(SliderSerializers.Meta):
fields = (
'images',
'section',
'tag',
)
Комментарии:
1. получена ошибка атрибута, в которой говорится, что этот объект ‘SliderImage’ не имеет атрибута ‘slider_image’
2. как вы сериализуете набор запросов? Можете ли вы показать свой фрагмент кода, который использовался для сериализации данных?
3. Спасибо, почти сработало, но изображения поступают не по этому шаблону 34.202.219.142:8000 /media /promotion / slider / … вместо этого добрался до этого ——>>>>media/promotion / slider / slider_56cc1829-aa78-40e3-9163-2c7297358de0.png какие-либо улучшения?