【问题标题】:How to handle an exception in a Django Middleware?如何处理 Django 中间件中的异常?
【发布时间】:2019-05-23 09:36:04
【问题描述】:

我在 Django 中间件中正确处理异常时遇到问题。 我的例外:

from rest_framework.exceptions import APIException
from rest_framework.status import HTTP_403_FORBIDDEN
class MyProfileAuthorizationError(APIException):    
    def __init__(self, msg):
        APIException.__init__(self, msg)
        self.status_code = HTTP_403_FORBIDDEN
        self.message = msg

还有我的中间件:

class PatchRequestUserWithProfile:
def __init__(self, get_response):
    self.get_response = get_response

def __call__(self, request, *args, **kwargs):
    patch_request_for_nonanon_user(request)
    if not request.user.profile:
        raise MyProfileAuthorizationError("You are not allowed to use this profile.")

    response = self.get_response(request)
    return response

这个异常抛出 500 而不是 403。我该如何解决这个问题?

【问题讨论】:

  • 可以添加错误回溯吗?
  • MyProfileAuthorizationError 这返回 500 ?
  • @gachdavit 是的,是的。看起来它没有作为 http 异常处理,而是像通常的错误引发一样。

标签: python django django-rest-framework middleware


【解决方案1】:

尝试返回 HttpResponseForbidden 响应而不是引发异常

from django.http import HttpResponseForbidden


class PatchRequestUserWithProfile:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request, *args, **kwargs):
        patch_request_for_nonanon_user(request)
        if not request.user.profile:
            return HttpResponseForbidden("You are not allowed to use this profile.")

        response = self.get_response(request)
        return response

【讨论】:

  • 轰隆隆!就是这样!非常感谢!我也尝试过返回响应,但不知道 HttpResponseForbidden 的存在。
【解决方案2】:

我认为你应该使用permissions,而不是使用中间件:

from rest_framework import permissions

class CustomAccessPermission(permissions.BasePermission):
    message = 'You are not allowed to use this profile.'

    def has_permission(self, request, view):
       if not request.user.profile:
           return False
       return True

并将其添加到 DEFAULT_PERMISSION_CLASSES 以使其可用于每个 API 视图。

'DEFAULT_PERMISSION_CLASSES': (
   'path.to.CustomAccessPermission',
)

【讨论】:

  • 不,如果我在这里调用 super - 它不会返回任何内容,我已经测试过 - 应用程序不会返回任何响应。
  • 抱歉,it does not return anything 是什么意思?
  • 这意味着在这种情况下我没有得到应用程序的任何响应 - 它处理
  • 但在这种情况下,我必须将此权限分配给整个项目中的所有视图集?
  • 不,它将被添加到所有视图集中。如果您希望某些视图集具有不同的行为,则需要覆盖它们的 permission_classes 属性。
【解决方案3】:

试试这个例外:

from rest_framework.exceptions import APIException

class MyProfileAuthorizationError(APIException):
    status_code = 403
    default_detail = 'You are not allowed to use this profile'
    default_code = 'forbidden'

我认为你不能这样做,请阅读:https://groups.google.com/forum/#!topic/django-developers/-ncPqVzF8W8

【讨论】:

  • 同样的问题仍然存在 - 得到 500 而不是 403
猜你喜欢
  • 2018-06-18
  • 1970-01-01
  • 2017-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-30
  • 2023-03-10
  • 1970-01-01
相关资源
最近更新 更多