gpt4 book ai didi

Django Rest Framework 使用 SerializerMethodField 返回相对路径而不是完整 url

转载 作者:行者123 更新时间:2023-12-03 08:53:03 25 4
gpt4 key购买 nike

我遇到了一个奇怪的问题。我一直在使用 Django 和 DRF 以及前端的 React 来开发一个应用程序。我的应用程序有两个模型:放置和覆盖。每个地方都有封面图片,这是数据库架构。

图像表

+----+---------------------+----------+----------------------+
| pk | file | title | description |
+----+---------------------+----------+----------------------+
| 1 | /media/my-image.jpg | My Image | My Image Description |
+----+---------------------+----------+----------------------+

放置 table

+----+------+-------+
| 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。但我只是好奇为什么这不适用于 SerializerMethodFieldAPIView。我希望如果您知道的话,您也许能够帮助我了解这里发生的事情。


最佳答案

您需要使请求可供序列化程序使用,如下所示:

return Response(PlaceDetailSerializer(place, context={'request': request}).data)

return ImageSerializer(place.cover, context={'request': request}).data

通常,Django Rest Framework 会为您执行此操作,但如果您手动调用序列化器类(例如在 MethodField 中),则还必须将请求作为上下文变量传递。

查看how the FileField is serialized :

request = self.context.get('request', None)
if request is not None:
return request.build_absolute_uri(url)
return url

如果您不将请求作为上下文变量传递,序列化程序将无法构建绝对 URL。

关于Django Rest Framework 使用 SerializerMethodField 返回相对路径而不是完整 url,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57728217/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com