在空列表上获取请求返回200状态代码

时间:2018-12-15 11:47:51

标签: django django-rest-framework

我有这个观点:

def get(self,request):
    cities = City.objects.filter(State__in=request.GET.getlist('state_id'))
    serializer = citySerializers(cities,many=True)
    return Response({"message": "data loaded!", "data": serializer.data})

如果我输入数据库中不存在的state_id,它将返回状态代码200,我希望它返回404以获取空列表。我做错了什么?

2 个答案:

答案 0 :(得分:3)

ORM查询将转换为:

cities = City.objects.filter(State__in=request.GET.getlist('state_id'))

变成这样:

SELECT *
FROM city
WHERE state_id IN (1,4,5)

实际上使用145存储在请求(state_id)中的值。但是数据库没有验证145是否是真实的主键值,也没有验证没有城市匹配的事实是一个问题:在这种情况下,结果很简单空的。

如果我们不关心state_id是否有效,而只想在找不到City的情况下返回404,则可以使用get_list_or_404 [Django-doc]函数:

from django.shortcuts import get_list_or_404

def get(self,request):
    cities = get_list_or_404(City, State__in=request.GET.getlist('state_id'))
    serializer = citySerializers(cities, many=True)
    return Response({"message": "data loaded!", "data": serializer.data})

但是,如果某些state_id是无效的(只要至少一个是有效的,并且一个在城市上绘制,我们就可以了),这仍然不会产生404。

如果state_id包含无效的State,例如,我们也可以引发404

from django.http import Http404
from django.shortcuts import get_list_or_404

def get(self,request):
    state_ids = set(request.GET.getlist('state_id'))
    if len(State.objects.filter(pk=state_ids)) != len(state_ids):
        raise Http404
    cities = get_list_or_404(City, State__in=state_ids)
    serializer = citySerializers(cities, many=True)
    return Response({"message": "data loaded!", "data": serializer.data})

答案 1 :(得分:0)

当您查找服务器找不到的特定对象时,将返回HTTP 404。这不适用于您试图获取所有对象或基于某些条件(过滤器)的列表的列表端点。空列表非常有效,因此返回200非常正确