How*_*ott 2 django django-models django-serializer django-rest-framework
我遇到一个奇怪的问题。我一直在使用 Django 和 DRF 以及前端的 React 来开发一个应用程序。我的应用程序有两个模型:放置和覆盖。每个地方都有封面图片,这是数据库架构。
图像表
+----+---------------------+----------+----------------------+
| pk | file | title | description |
+----+---------------------+----------+----------------------+
| 1 | /media/my-image.jpg | My Image | My Image Description |
+----+---------------------+----------+----------------------+
Run Code Online (Sandbox Code Playgroud)
餐位表
+----+------+-------+
| pk | code | cover |
+----+------+-------+
| 1 | abcd | 1 |
+----+------+-------+
Run Code Online (Sandbox Code Playgroud)
我的操作很简单。我将使用地点代码请求地点详细信息,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'
Run Code Online (Sandbox Code Playgroud)
这是请求的输出
{
"code": "3469324020",
"cover": {
"pk": 13,
"file": "http://127.0.0.1:8000/media/my-image.jpg ",
"title": "My Image",
"description": ""
}
}
Run Code Online (Sandbox Code Playgroud)
到目前为止一切都很好。因为我想要我的图像的完整网址,而这正是我所得到的。但是当我开始使用的时候就出现了问题SerializerMethodField()
class PlaceDetailSerializer(ModelSerializer):
cover = SerializerMethodField()
def get_cover(self, place):
return ImageSerializer(place.cover).data
class Meta:
model = Place
fields = ["code", "cover"]
Run Code Online (Sandbox Code Playgroud)
这是更改后的新响应
{
"code": "3469324020",
"cover": {
"pk": 13,
"file": "/media/my-image.jpg",
"title": "My Image",
"description": ""
}
}
Run Code Online (Sandbox Code Playgroud)
看?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)
Run Code Online (Sandbox Code Playgroud)
它还将返回相对 url 作为输出。
现在我知道有一些方法可以使用get_absolute_url()或其他函数返回完整的 url。但我只是好奇为什么这不适用于SerializerMethodFieldor APIView。我希望如果您知道的话,您也许能够帮助我了解这里发生的事情。
小智 5
您需要使请求可供序列化器使用,如下所示:
return Response(PlaceDetailSerializer(place, context={'request': request}).data)
return ImageSerializer(place.cover, context={'request': request}).data
Run Code Online (Sandbox Code Playgroud)
通常,Django Rest Framework 会为您执行此操作,但如果您手动调用序列化器类(例如在 MethodField 中),则还必须将请求作为上下文变量传递。
request = self.context.get('request', None)
if request is not None:
return request.build_absolute_uri(url)
return url
Run Code Online (Sandbox Code Playgroud)
如果您不将请求作为上下文变量传递,则序列化程序无法构建绝对 URL。
| 归档时间: |
|
| 查看次数: |
1722 次 |
| 最近记录: |