django - Django Rest Framework 使用 SerializerMethodField 返回相对路径而不是完整 url
问题描述
我遇到了一个奇怪的问题。我一直在使用 Django 和 DRF 以及在前端做出反应来开发应用程序。我的应用有两个模型,Place 和 Cover。每个地方都有一个封面图片,这里是数据库模式。
图像表
+----+---------------------+----------+----------------------+
| pk | file | title | description |
+----+---------------------+----------+----------------------+
| 1 | /media/my-image.jpg | My Image | My Image Description |
+----+---------------------+----------+----------------------+
放置表
+----+------+-------+
| pk | code | cover |
+----+------+-------+
| 1 | abcd | 1 |
+----+------+-------+
我的操作很简单。我将使用地点代码请求地点详细信息,DRF 将返回详细信息。这是我最初写的。
class ImageSerializer(ModelSerializer):
class Meta:
model = Image
fields = ["pk", "file", "title", "description"]
class PlaceDetailSerializer(ModelSerializer):
cover = ImageSerializer()
class Meta:
model = Place
fields = ["code", "cover"]
class PlaceDetailView(RetrieveAPIView):
serializer_class = PlaceDetailSerializer
permission_classes = []
queryset = Place.objects.filter(deleted=False, published=True)
lookup_field = 'code'
lookup_url_kwarg = 'code'
这是请求的输出
{
"code": "3469324020",
"cover": {
"pk": 13,
"file": "http://127.0.0.1:8000/media/my-image.jpg ",
"title": "My Image",
"description": ""
}
}
到目前为止一切都很好。因为我想要我的图片的完整网址,而这正是我所拥有的。但是当我开始使用时就会出现问题SerializerMethodField()
class PlaceDetailSerializer(ModelSerializer):
cover = SerializerMethodField()
def get_cover(self, place):
return ImageSerializer(place.cover).data
class Meta:
model = Place
fields = ["code", "cover"]
这是更改后的新响应
{
"code": "3469324020",
"cover": {
"pk": 13,
"file": "/media/my-image.jpg",
"title": "My Image",
"description": ""
}
}
看?DRF 不再返回绝对 URL,而是返回相对 URL。我很好奇为什么会这样?它与 DRF 上下文参数有关吗?
我还注意到绝对 url 也不适用于 APIView。
class PlaceDetailSerializer(ModelSerializer):
cover = ImageSerializer()
class Meta:
model = Place
fields = ["code", "cover"]
class PlaceDetailView( APIView ):
serializer_class = PlaceDetailSerializer
permission_classes = []
queryset = Place.objects.filter(deleted=False, published=True)
lookup_field = 'code'
lookup_url_kwarg = 'code'
def get(self, request, *args, **kwargs):
place = Place.objects.get(code=kwargs.get("code"))
return Response(PlaceDetailSerializer(place).data)
它还将返回相对 url 作为输出。
现在我知道有一些方法可以使用get_absolute_url()
或其他函数返回完整的 url。但我只是好奇为什么这不适用于SerializerMethodField
or APIView
。我希望如果你知道,你可以帮助我理解这里发生了什么。
解决方案
您需要使请求对序列化程序可用,如下所示:
return Response(PlaceDetailSerializer(place, context={'request': request}).data)
return ImageSerializer(place.cover, context={'request': request}).data
通常,Django Rest Framework 会为您执行此操作,但如果您手动调用序列化程序类(例如在 MethodField 中),您还必须将请求作为上下文变量传递。
request = self.context.get('request', None)
if request is not None:
return request.build_absolute_uri(url)
return url
如果您不将请求作为上下文变量传递,则序列化程序无法构建绝对 URL。
推荐阅读
- android - 使用 Firestore 按键入的字母搜索
- google-cloud-platform - Google Cloud - 从不同的电子邮件地址使用了错误的项目 ID
- paypal - IPN 模拟器说接受,但验证总是返回“无效”
- c# - 在使用内存流作为 TiffBitmap 解码器的输入时需要帮助
- awk - 如何匹配 2 个文件并导出到输出?
- node.js - 将 process.env 转换为
与 TS - javascript - 变量范围问题(nodejs/javascript)
- raku - 如何计算模块的 dist 哈希
- lisp - Lisp - 如何在另一个函数中调用一个函数?
- python - 在 Linux 上自动安装 conda