使用django_rest_framework引发异常

时间:2015-12-30 15:22:51

标签: python django python-2.7 exception-handling django-rest-framework

我写了一个视图,解密GPG加密文件并将其作为纯文本返回。这一般工作正常。问题是,如果文件为空或者包含无效的GPG数据,gnupg将返回一个空结果而不是抛出异常。

我需要能够在 decrypt_file 中执行此类操作,以检查解密是否失败并引发错误:

if data.ok:
    return str(data)
else:
    raise APIException(data.status)

如果我这样做,我会在Django调试输出中看到APIException,但它没有转换为对客户端的500响应。相反,客户端获得200响应,空体。我可以在 get 方法中引发APIException并发送500响应,但是我无法访问gnupg错误消息。

以下是我的观点的简化版本:

from rest_framework.views import APIView
from django.http import FileResponse
from django.core import files
from gnupg import GPG

class FileDownload(APIView):
    def decrypt_file(self, file):
        gpg = GPG()
        data = gpg.decrypt(file.read())
        return data

    def get(self, request, id, format=None):
        f = open('/tmp/foo', 'rb')
        file = files.File(f)
        return FileResponse(self.decrypt_file(file))

我已阅读有关DRF异常处理here的文档,但似乎并未提供此问题的解决方案。我对Django和python很新,所以我完全有可能错过一些明显的东西。有用的建议将不胜感激。感谢。

1 个答案:

答案 0 :(得分:0)

如果你在python中引发错误,跟踪中的每个函数都会重新提升它,直到有人抓住它。您可以先声明一个例外:

from rest_framework.exceptions import APIException

class ServiceUnavailable(APIException):
    status_code = 503
    default_detail = 'Service temporarily unavailable, try again later.'

然后在decrypt_file函数中,如果解密不成功,则引发此异常。您可以传递参数来修改消息。然后,在get方法中,您应该调用decrypt_file函数并将您的文件作为参数传递。如果出现任何问题,你的函数会引发异常然后,get方法重新引发它,直到Django Rest Framework异常处理程序捕获它为止。
编辑:
在您的解密函数中,执行以下操作:

from rest_framework.response import Response

def decrypt_file(self, file):
    ... # your codes
    if data.ok:
        return str(data)
    else:
        raise ServiceUnavailable

def get(self, request, id, format=None):
    f = open('/tmp/foo', 'rb')
    result = decrypt_file(f)
    f.close()
    return Response({'data': result})