Не удается получить полный URL-адрес поля изображения Django Rest

У меня есть два сериализатора:

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)})
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
73
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Только не пытайтесь переопределить поле 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"
            }
        ]
    }
]

Не работает, исключение :(

Anonymous Wizard 11.02.2023 12:09

Какое исключение, также не могли бы вы добавить свои модели к вопросу?

Niko 11.02.2023 15:29

Исключение, этот сериализатор ничего не знает о url. Хорошо, добавлю через несколько минут

Anonymous Wizard 11.02.2023 17:16

Поскольку в вашей модели нет атрибута url, он называется image. Итак, измените поля AlbumImageSerializer на: fields = ['id', 'image']

Niko 11.02.2023 18:40

Могу я задать вам еще один вопрос? Когда я делаю это в методе post и создаю alb_img = AlbumImage(album=album, image=file), когда я использую print(alb_img.image), он печатает URL-адрес, например: http://localhost:8000/media/UUID/random_image_two.png, есть ли варианты распечатать его без UUID?

Anonymous Wizard 11.02.2023 18:46

Это еще один endpoint для создания изображений? Я немного запутался, в любом случае вы должны использовать сериализатор для создания объектов, например. MySerializer(request.data). Если вы можете добавить свое мнение к вопросу, я могу дать более конкретный ответ.

Niko 11.02.2023 19:22

Да, это еще одна конечная точка, я добавил это к вопросу

Anonymous Wizard 11.02.2023 19:28

Извините за поздний ответ. Это немного странно, он должен печатать только имя файла. В любом случае вы можете использовать запрос на его сборку: url = request.build_absolute_uri(alb_img.image.url) затем return Response({'id': pk, 'url': url}). Хотя я должен еще раз указать, что вы должны использовать AlbumImageSerializer для проверки данных перед их сохранением.

Niko 12.02.2023 15:36

Спасибо, да, я уже нашел это решение с build_absolute_uri, но просто интересно, почему сам сериализатор правильно отображает адрес, а в данном случае добавляет id

Anonymous Wizard 13.02.2023 12:27

В поверхностном объяснении это потому, что 'id' указан в полях и форме, как DRF работает с models.ImageField. Конечно, если вы хотите углубиться, вы всегда можете изучить serializers.ModelSerializer код, нажав cmd (или crtl) + щелчок левой кнопкой мыши. :)

Niko 13.02.2023 18:01

Другие вопросы по теме