Django REST Framework и абсолютный URL FileField

Проект GitHub / Nuget называется MetaLinq , целью которого является упрощение работы с выражением tress.

Он преобразует между нормальными выражениями и «EditableExpressions», которые являются изменяемыми и полностью Serializable, поэтому их можно использовать с Json, Xml, Binary и т. д.

Также проверьте это сообщение для получения дополнительной информации.

23
задан Mark Semsel 28 May 2014 в 18:01
поделиться

6 ответов

Попробуйте SerializerMethodField

Пример (не проверено):

class MySerializer(serializers.ModelSerializer):
    thumbnail_url = serializers.SerializerMethodField('get_thumbnail_url')

    def get_thumbnail_url(self, obj):
        return self.context['request'].build_absolute_uri(obj.thumbnail_url)

Запрос должен быть доступен для сериализатора, чтобы он мог создать полный абсолютный URL для вас. Один из способов заключается в том, чтобы явно передать его при создании сериализатора, подобно этому:

serializer = MySerializer(account, context={'request': request})
43
ответ дан Alexandros B 28 May 2014 в 18:01
поделиться

Нет необходимости в переопределениях или настройках. DRF обрабатывает это автоматически. Взгляните на метод to_representation из FileField:

def to_representation(self, value):
    if not value:
        return None

    use_url = getattr(self, 'use_url', api_settings.UPLOADED_FILES_USE_URL)

    if use_url:
        if not getattr(value, 'url', None):
            # If the file has not been saved it may not have a URL.
            return None
        url = value.url
        request = self.context.get('request', None)
        if request is not None:
            return request.build_absolute_uri(url)
        return url
    return value.name

Обратите внимание, что он не будет работать, если контекст сериализатора не установлен должным образом. Если вы используете ViewSet, не беспокойтесь, все делается тихо, но если вы создаете экземпляр сериализатора вручную, вы должны передать запрос в контексте.

context = {'request': request}
serializer = ExampleSerializer(instance, context=context)
return Response(serializer.data)

https://www.django-rest-framework.org/community/3.0-announcement/#file-fields-as-urls

3
ответ дан ukrutt 28 May 2014 в 18:01
поделиться

Просто передайте контекст и передайте объект запроса. если вы используете @api_view

serializer = CustomerSerializer(customer, context={"request": request})

Для пользователя ViewSet метод get_serializer_context

class ProjectViewSet(viewsets.ModelViewSet):
queryset = Project.objects.all()
serializer_class = ProjectSerializer

def get_serializer_context(self):
    return {'request': self.request}
1
ответ дан Tarikul Islam Rasel 28 May 2014 в 18:01
поделиться

Чтобы получить URL-адрес файла, который использует FileField, вы можете просто вызвать атрибут url у FieldFile (это экземпляр файла, а не поле), он использует класс Storage для определения URL-адреса для этого файла. Это очень просто, если вы используете внешнее хранилище, такое как Amazon S3, или если ваше хранилище меняется.

get_thumbnail_url будет выглядеть следующим образом.

def get_thumbnail_url(self, obj):
    return obj.thumbnail.url

Вы также можете использовать его в шаблоне следующим образом:

{{ current_project.thumbnail.url }}
6
ответ дан Johnny Well 28 May 2014 в 18:01
поделиться

Спасибо, Шавенвартог. Ваш пример и справочная документация очень помогли. Моя реализация немного отличается, но очень близка к тому, что вы опубликовали:

from SomeProject import settings

class ProjectSerializer(serializers.HyperlinkedModelSerializer):

    thumbnail_url = serializers.SerializerMethodField('get_thumbnail_url')

    def get_thumbnail_url(self, obj):
        return '%s%s' % (settings.MEDIA_URL, obj.thumbnail)

    class Meta:
        model = Project
        fields = ('id', 'url', 'name', 'thumbnail_url') 
7
ответ дан Mark Semsel 28 May 2014 в 18:01
поделиться

Проверьте свои настройки.py

настройки мультимедиа.

У меня была та же ошибка, и я обнаружил, что:

MEDIA_URL = '/ media /' добились цели.

Раньше у меня было только:

MEDIA_URL = 'media /'

1
ответ дан jakobdo 28 May 2014 в 18:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: