Запрос ORM преобразуется в:
cities = City.objects.filter(State__in=request.GET.getlist('state_id'))
во что-то вроде:
SELECT *
FROM city
WHERE state_id IN (1,4,5)
с 1
, 4
и 5
, в действительности значения хранятся взапрос (state_id
).Но база данных не проверяет, являются ли 1
, 4
и 5
действительными значениями первичного ключа, а также тот факт, что ни один из городов не совпадает, не является проблемой: в этом случае результат просто пуст.
Если нам не важно, действительны ли state_id
, но мы хотим вернуть 404 только в том случае, если нет City
, мы можем использовать 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})
Но это все равно не даст 404, если некоторые state_id
с являются недопустимыми (если хотя бы один из них действителен, и тот, который отображаетсяв городе у нас все хорошо).
Мы также можем поднять 404, если state_id
содержит недействительный State
, например, с:
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})