Mar*_*sel 27 python django url filefield
我已经定义了一个包含以下模型的简单Django应用程序:
class Project(models.Model):
name = models.CharField(max_length=200)
thumbnail = models.FileField(upload_to='media', null=True)
Run Code Online (Sandbox Code Playgroud)
(从技术上讲,这可能是一个ImageField.)
在模板中,将MEDIA_URL值(在settings.py中正确编码)作为缩略图URL的前缀包含在内是很容易的.以下工作正常:
<div id="thumbnail"><img src="{{ MEDIA_URL }}{{ current_project.thumbnail }}" alt="thumbnail" width="400" height="300" border="0" /></div>
Run Code Online (Sandbox Code Playgroud)
使用DRF,我定义了一个名为ProjectSerializer的HyperlinkedModelSerializer后代:
class ProjectSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Project
fields = ( 'id' ,'url', 'name', 'thumbnail')
Run Code Online (Sandbox Code Playgroud)
我已经定义了一个非常简单的ModelViewSet后代:
class ProjectViewSet(viewsets.ModelViewSet):
queryset = Project.objects.all()
serializer_class = ProjectSerializer
Run Code Online (Sandbox Code Playgroud)
生成的JSON示例如下所示:
{
"id": 1,
"url": "http://localhost:8000/api/v1/projects/1/",
"name": "Institutional",
"thumbnail": "media/institutional_thumb_1.jpg"
}
Run Code Online (Sandbox Code Playgroud)
我还没有弄清楚如何在项目的JSON表示中提供包含图像完整URL的缩略图字段.
我认为我需要在ProjectSerializer中创建一个自定义字段,但还没有成功.
joh*_*all 48
示例(未经测试):
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)
Run Code Online (Sandbox Code Playgroud)
该请求必须可供序列化程序使用,因此它可以为您构建完整的绝对URL.一种方法是在创建序列化程序时显式传入它,类似于:
serializer = MySerializer(account, context={'request': request})
Run Code Online (Sandbox Code Playgroud)
谢谢,shavenwarthog.您的示例和文档参考帮助极大.我的实现略有不同,但与您发布的内容非常接近:
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')
Run Code Online (Sandbox Code Playgroud)
小智 6
要获取使用FileField的文件的url,您只需调用FieldFile的url属性(这是文件实例而不是字段),它使用Storage类来确定此文件的URL.如果您使用Amazon S3等外部存储或存储更改,则非常简单.
get_thumbnail_url就是这样的.
def get_thumbnail_url(self, obj):
return obj.thumbnail.url
Run Code Online (Sandbox Code Playgroud)
您也可以这样在模板中使用它:
{{ current_project.thumbnail.url }}
Run Code Online (Sandbox Code Playgroud)
我发现为序列化方法字段编写相同的代码很烦人。如果您已正确设置了MEDIA_ROOTS3 存储桶 URL,则可以向序列化程序添加一个字段,例如:
class ProjectSerializer(serializers.ModelSerializer):
logo_url = serializers.URLField(read_only=True, source='logo.url')
class Meta:
model = Project
Run Code Online (Sandbox Code Playgroud)
logo 是模型中的 ImageField。它不能为空,以避免出现类似的错误ValueError: The 'img' attribute has no file associated with it.
我只.build_absolute_uri在序列化程序方法字段中使用来返回在我的 API 中使用其他视图的绝对 url。例如,在我的项目中,有一个/webviews/projects/<pk>显示URL 、一个标题和一个收集一些用户输入的按钮(即不完全是你会用后缀做什么,因为它不是资源的简单表示,而是包含一些逻辑)。终点/projects/<pk>/包含一个字段“webview_url”,它是用 SerializerMethodField 生成的。这不是媒体。
无需任何覆盖或自定义。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
Run Code Online (Sandbox Code Playgroud)
请注意,如果序列化程序的上下文设置不正确,它将无法工作。如果您使用ViewSet的是s,不用担心,一切都是静默完成的,但是如果您手动实例化序列化程序,则必须在上下文中传递请求。
context = {'request': request}
serializer = ExampleSerializer(instance, context=context)
return Response(serializer.data)
Run Code Online (Sandbox Code Playgroud)
https://www.django-rest-framework.org/community/3.0-announcement/#file-fields-as-urls
| 归档时间: |
|
| 查看次数: |
22543 次 |
| 最近记录: |