Django get_queryset返回500而不是404

时间:2018-07-19 15:04:41

标签: django django-models django-rest-framework django-views

这是我的观点:

class SampleViewSet(viewsets.ModelViewSet):
      serializer_class = SampleSerializer
      queryset = Sample.objects.all()

      def get_queryset(self):
          queryset = self.queryset
          test_code = self.request.query_params.get('test_code', None)
          if test_code is not None:
             queryset = queryset.filter(test__test_code=test_code)
          return queryset

这是我的模特:

class Sampe(models.Model):
      test = models.OneToOneField(Test, null=True, blank=True, on_delete=models.CASCADE)
      # few more fields- not so important

这是我的序列化器:

class SampleSerializer(serializers.ModelSerializer):
      test_code = serializers.CharField(source='test.test_code')

      class Meta:
           model = Sample
           fields = '__all__'

当我点击/ api / sample?test_code =“ existing_param”时,此方法有效 因此,当我执行/ api / sample?test_code =“ Not_Existing_param”时,我期望它应该抛出404,而抛出500测试匹配查询不存在。真的感谢任何帮助。

谢谢

1 个答案:

答案 0 :(得分:4)

问题是该函数将引发错误,并且Web服务器无法真正解释导致此错误的原因,因此,一般而言,引发500比404更准确

但是您可以做的是使用get_list_or_404,其作用类似于get_object_or_404,然后使用.filter(..)而不是.get(..)

from django.shortcuts import get_list_or_404

class SampleViewSet(viewsets.ModelViewSet):
      serializer_class = SampleSerializer
      queryset = Sample.objects.all()

      def get_queryset(self):
          queryset = self.queryset
          test_code = self.request.query_params.get('test_code', None)
          if test_code is not None:
             queryset = get_list_or_404(queryset, test__test_code=test_code)
          return queryset

因此,这将过滤查询集,并在结果查询集为空的情况下引发404异常。如果您将 chain 过滤器放在一起,那么在最后一个元素上执行此操作就足够了,因为这样您就可以检查将要返回的实际查询集,从而避免检查稍后在过程中不使用的多个查询器