У меня есть два сериализатора:
class AlbumImageSerializer(serializers.ModelSerializer):
url = serializers.SerializerMethodField('get_url')
def get_url(self, obj):
return obj.image.url
class Meta:
model = AlbumImage
fields = ['id', 'url']
class PhotoAlbumSerializer(serializers.ModelSerializer):
photos = AlbumImageSerializer(many=True, read_only=True)
class Meta:
model = PhotoAlbum
fields = ('id', 'name', 'photos')
И я прочитал, что для отображения полного URL-адреса изображения достаточно передать контекст запроса для вызова сериализатора, например:
serialized = SomeSerializer(some, context = {"request": request})
А когда вы используете ViewSet
, вам не нужно ничего делать, DRF автоматически передаст контекст запроса при инициализации сериализатора.
Я использую ViewSets, например:
class PhotoAlbumViewSet(mixins.CreateModelMixin,
mixins.ListModelMixin,
GenericViewSet):
serializer_class = PhotoAlbumSerializer
но все же мой запрос на получение возвращает ответ, например:
"url": "/media/images/photo.jpg"
Как я могу получить
"url": "127.0.0.1:8000/media/images/photo.jpg"
В моем случае?
Мои модели
class PhotoAlbum(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, auto_created=True)
name = models.CharField(max_length=50, verbose_name='Pet name')
class AlbumImage(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, auto_created=True)
album = models.ForeignKey(PhotoAlbum, on_delete=models.CASCADE, related_name='photos')
image = models.ImageField(upload_to='images/', height_field=None, width_field=None, max_length=100, blank=True)
Еще одна конечная точка, где print url
возвращает ответ вроде 127.0.0.1:8000/media/UUID/photo.jpg
:
@action(methods=['post'], detail=True)
def photo(self, request, pk):
file = request.data['file']
album = PhotoAlbum.objects.get(pk=pk)
alb_img = AlbumImage(album=album, image=file)
alb_img.save()
return Response({'id': pk,
'url': alb_img.image)})
Только не пытайтесь переопределить поле URL, пусть фреймворк позаботится об этом за вас:
сериализаторы.py
class AlbumImageSerializer(serializers.ModelSerializer):
class Meta:
model = models.AlbumImage
fields = ['id', 'url']
class PhotoAlbumSerializer(serializers.ModelSerializer):
photos = AlbumImageSerializer(many=True, read_only=True)
class Meta:
model = models.Pet
fields = ('id', 'name', 'photos')
образец вывода:
[
{
"id": 1,
"name": "Pet name.",
"photos": [
{
"id": 2,
"url": "http://localhost:8000/media/random_image_one.png"
},
{
"id": 3,
"url": "http://localhost:8000/media/random_image_two.png"
}
]
}
]
Какое исключение, также не могли бы вы добавить свои модели к вопросу?
Исключение, этот сериализатор ничего не знает о url
. Хорошо, добавлю через несколько минут
Поскольку в вашей модели нет атрибута url
, он называется image
. Итак, измените поля AlbumImageSerializer
на: fields = ['id', 'image']
Могу я задать вам еще один вопрос? Когда я делаю это в методе post
и создаю alb_img = AlbumImage(album=album, image=file)
, когда я использую print(alb_img.image)
, он печатает URL-адрес, например: http://localhost:8000/media/UUID/random_image_two.png
, есть ли варианты распечатать его без UUID
?
Это еще один endpoint
для создания изображений? Я немного запутался, в любом случае вы должны использовать сериализатор для создания объектов, например. MySerializer(request.data)
. Если вы можете добавить свое мнение к вопросу, я могу дать более конкретный ответ.
Да, это еще одна конечная точка, я добавил это к вопросу
Извините за поздний ответ. Это немного странно, он должен печатать только имя файла. В любом случае вы можете использовать запрос на его сборку: url = request.build_absolute_uri(alb_img.image.url)
затем return Response({'id': pk, 'url': url})
. Хотя я должен еще раз указать, что вы должны использовать AlbumImageSerializer
для проверки данных перед их сохранением.
Спасибо, да, я уже нашел это решение с build_absolute_uri
, но просто интересно, почему сам сериализатор правильно отображает адрес, а в данном случае добавляет id
В поверхностном объяснении это потому, что 'id'
указан в полях и форме, как DRF работает с models.ImageField
. Конечно, если вы хотите углубиться, вы всегда можете изучить serializers.ModelSerializer
код, нажав cmd (или crtl) + щелчок левой кнопкой мыши. :)
Не работает, исключение :(