You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DRF中ModelViewSet与函数视图返回ImageField结果不一致问题

问题:DRF中ModelViewSet与函数视图返回ImageField结果不一致

我使用Django Rest Framework构建示例应用时,发现代表用户评分的Rating模型的ImageField字段,在ModelViewSet和基于函数的视图中返回结果不一致:

  • ModelViewSet请求返回完整URL:"photo": "http://127.0.0.1:8000/media/images/ratings/image.jpg"
  • 函数视图请求仅返回相对路径:"photo": "/media/images/ratings/image.jpg"

相关代码

Rating模型

class Rating(models.Model):
    
    user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE)
    rating = models.IntegerField()
    review = models.CharField(max_length=500)
    recipe = models.ForeignKey(Recipe,on_delete=models.CASCADE, related_name='ratings')
    published_date = models.DateField(default=date.today)
    updated_date = models.DateField(default=date.today)
    photo = models.ImageField(upload_to='images/ratings/', blank=True)

RatingViewSet代码

class RatingViewSet(viewsets.ModelViewSet):
    serializer_class = RatingSerializer
    lookup_fields = ('id', 'recipe')
    filter_backends = [DjangoFilterBackend]
    filterset_class = RatingFilter 

    queryset = Rating.objects.all()

    def perform_create(self, serializer):
        serializer.save(user=self.request.user)

    def perform_update(self, serializer):
        serializer.save(updated_date=date.today())

函数视图代码

@api_view(['GET'])
def UserRating(request):
    recipe_id = request.query_params.get('recipe_id')

    try:
        rating = Rating.objects.filter(recipe=recipe_id, user=request.user).latest('updated_date')
        serializer = RatingSerializer(rating)

        return Response(serializer.data, status=status.HTTP_200_OK)
    except Rating.DoesNotExist:
        return Response({})

原因

DRF的ModelViewSet会自动将当前请求的request对象传入序列化器的上下文(context)中,而序列化器的ImageField字段需要依赖这个上下文来生成包含域名、协议的完整绝对URL。

但在你的函数视图中,初始化RatingSerializer时没有手动传入request上下文,导致序列化器无法获取请求的域名信息,只能返回媒体文件的相对路径。

解决方案

在函数视图中初始化序列化器时,通过context参数传入当前request对象:

@api_view(['GET'])
def UserRating(request):
    recipe_id = request.query_params.get('recipe_id')

    try:
        rating = Rating.objects.filter(recipe=recipe_id, user=request.user).latest('updated_date')
        # 新增context参数传入request
        serializer = RatingSerializer(rating, context={'request': request})

        return Response(serializer.data, status=status.HTTP_200_OK)
    except Rating.DoesNotExist:
        return Response({})

这样修改后,函数视图返回的photo字段就会和ModelViewSet一样,生成完整的绝对URL。

内容的提问来源于stack exchange,提问作者Chowdahhh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 16:03:13