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
相关产品推荐
相关产品推荐

