Django REST中如何处理get_object的对象不存在问题?
问题解决方法
错误根源
你遇到的catching classes that do not inherit from BaseException is not allowed错误,是因为捕获的Foo.objects.DoesNotExist并非正确的异常类——DoesNotExist是定义在模型类Foo上的,而非模型管理器Foo.objects上,正确的捕获目标应该是Foo.DoesNotExist。
另外,用ValidationError抛出对象不存在的错误并不合适:ValidationError通常用于请求参数验证失败(对应HTTP 400状态码),而对象不存在属于资源未找到,应该返回HTTP 404状态码,Django REST Framework(DRF)提供了专门的NotFound异常来处理这种场景。
正确实现方式
方式一:修正异常捕获并使用DRF的NotFound异常
from rest_framework.generics import GenericAPIView from rest_framework.exceptions import NotFound from rest_framework.response import Response class FooViewSet(GenericAPIView): def get_object(self, pk): try: return Foo.objects.get(pk=pk) except Foo.DoesNotExist: raise NotFound('Foo Does Not Exist') def get(self, request, pk, format=None): obj = self.get_object(pk) return Response({}) def patch(self, request, pk, format=None): obj = self.get_object(pk) return Response({}) def delete(self, request, pk, format=None): obj = self.get_object(pk) return Response({})
方式二:使用快捷函数简化代码
DRF推荐使用get_object_or_404快捷函数,它会自动捕获Foo.DoesNotExist异常并抛出Http404,DRF会将其转换为标准的404响应,无需手动编写try-except逻辑:
from rest_framework.generics import GenericAPIView from django.shortcuts import get_object_or_404 from rest_framework.response import Response class FooViewSet(GenericAPIView): def get_object(self, pk): return get_object_or_404(Foo, pk=pk) def get(self, request, pk, format=None): obj = self.get_object(pk) return Response({}) def patch(self, request, pk, format=None): obj = self.get_object(pk) return Response({}) def delete(self, request, pk, format=None): obj = self.get_object(pk) return Response({})
内容的提问来源于stack exchange,提问作者Nikko
相关产品推荐
相关产品推荐

