我正在尝试处理 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)
如果没有保护错误,它会将我发送回我的列表页面,并显示删除成功消息,但对于受保护错误,它将我发送到一些通用错误页面,并在/settings/currency/1/delete/消息中使用 ProtectedError。
谢谢。
在我看来,在这两种情况下,您的回报都是相同的:
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)
看看这些例子
另一个可选,你也可以通过创建新的装饰器来处理它:
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):
....
CBV DeleteView使用表单(http://ccbv.co.uk/projects/Django/4.0/django.views.generic.edit/DeleteView/(,这是运行验证和处理错误的推荐方式。
def post(self, request, *args, **kwargs):
# Set self.object before the usual form processing flow.
# Inlined because having DeletionMixin as the first base, for
# get_success_url(), makes leveraging super() with ProcessFormView
# overly complex.
self.object = self.get_object()
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
只需使用自定义清理方法定义一个自定义表单类,并且仅定义具有 id 的字段即可检索对象:
https://docs.djangoproject.com/en/4.0/ref/forms/api/#django.forms.Form.clean