Проект GitHub / Nuget называется MetaLinq , целью которого является упрощение работы с выражением tress.
Он преобразует между нормальными выражениями и «EditableExpressions», которые являются изменяемыми и полностью Serializable, поэтому их можно использовать с Json, Xml, Binary и т. д.
Также проверьте это сообщение для получения дополнительной информации.
Попробуйте 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})
Нет необходимости в переопределениях или настройках. 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
Просто передайте контекст и передайте объект запроса. если вы используете @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}
Чтобы получить 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 }}
Спасибо, Шавенвартог. Ваш пример и справочная документация очень помогли. Моя реализация немного отличается, но очень близка к тому, что вы опубликовали:
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')
Проверьте свои настройки.py
настройки мультимедиа.
У меня была та же ошибка, и я обнаружил, что:
MEDIA_URL = '/ media /' добились цели.
Раньше у меня было только:
MEDIA_URL = 'media /'