Django:ProtectedError异常处理无法正常工作

时间:2019-02-06 12:04:15

标签: django django-models django-templates django-views

我正在尝试处理ProtectedError异常,并尝试在模板中发布自定义错误消息。

def delete(self, request, *args, **kwargs):
    obj = self.get_object()
    get_success_url = self.get_success_url()
    try:
        obj.delete()
        messages.success(self.request, self.success_message % obj.__dict__)
    except ProtectedError:
        messages.success(self.request, "can't delete")

    return super().delete(request, *args, **kwargs)

没有ProtectedError,它会将我发送回带有成功删除消息的列表页面,但对于ProtectedError,它会将我发送到某些常规错误页面,其中带有ProtectedError的消息位于/ settings / currency / 1 / delete /消息。

谢谢。

2 个答案:

答案 0 :(得分:0)

如我所见,在两种情况下,您的收益是相同的:

return super().delete(request, *args, **kwargs)

代替您,请引发错误:

raise ProtectedError('Cannot remove meta user instances', None)

或类似的东西

    try:
        obj.delete()
        return JsonResponse({})
    except ProtectedError as e:
        return self.status_msg(e[0], status=405) 

看看those examples

答案 1 :(得分:0)

另一个可选的,你也可以通过创建新的装饰器来处理:

from functools import wraps
from django.utils.translation import gettext_lazy as _
from django.db.models.deletion import ProtectedError
from rest_framework.exceptions import PermissionDenied


def protected_error_as_api_error():
    """
    Decorator to handle all `ProtectedError` error as API Error,
    which mean, converting from error 500 to error 403.
    """
    def decorator(func):
        @wraps(func)
        def wrapper(request, *args, **kwargs):
            try:
                return func(request, *args, **kwargs)
            except ProtectedError as error:
                raise PermissionDenied(_('Action Denied: The selected object is being used '
                                         'by the system. Deletion not allowed.'))
        return wrapper
    return decorator

用法示例:

from django.utils.decorators import method_decorator
from yourapp.decorators.protected_error_as_api_error import protected_error_as_api_error

@method_decorator(protected_error_as_api_error())
def delete(self, request, *args, **kwargs):
    ....


# OR


@method_decorator(protected_error_as_api_error())
def destroy(self, request, *args, **kwargs):
    ....


# OR

@action(methods=['delete'], ...):
@method_decorator(protected_error_as_api_error())
def your_view_name(self, request, *args, **kwargs):
    ....
相关问题