【发布时间】:2025-04-13 11:40:01
【问题描述】:
在 django 视图中,如何显示模型引发的错误?
这是quesiton 的后续问题。
【问题讨论】:
标签: django model-view-controller view model business-logic
在 django 视图中,如何显示模型引发的错误?
这是quesiton 的后续问题。
【问题讨论】:
标签: django model-view-controller view model business-logic
实际上,Django 比 从 1 岁婴儿那里偷一块蛋糕更容易。 您只需在应添加到 MIDDLEWARE_CLASSES 的类中编写一个process_exception() 函数。基于此,您可以将错误处理走得很远。
您可以在项目根目录中创建一个 middleware.py 文件。然后将其添加到设置中:
MIDDLEWARE_CLASSES = [
# [....] all other middlewares above
'middleware.ExceptionMiddleware',
]
如果你有很棒的 django-sentry,你可能只想处理一些异常,剩下的交给 django-sentry。在这种情况下,您可以创建这样的设置:
EXCEPTION_MIDDLEWARE_HANDLES = [
'ServerOverloaded',
# [...] other exception class names that you want to handle in your middleware
'BetTooLateException',
]
我将向您展示一个示例中间件,它实现了 process_request() 并处理类名在 EXCEPTION_MIDDLEWARE_HANDLES 中的异常。它可能不完全适合您的需要,但它确实是trivial to adapt to your own needs:
from django import http
from django import template
from django.template import loader
from django.conf import settings
class ExceptionMiddleware(object):
def process_exception(self, request, exception):
if settings.DEBUG: # don't do anything in debug mode
return None
# here i use a setting because i want some exception to be caught by sentry
# but you can remove this if you want your middleware to handle all exceptions
if exception.__class__.__name__ not in settings.EXCEPTION_MIDDLEWARE_HANDLES:
return None
# time to prepare the error response
context = {
'error': exception.__class__.__name__,
'exception': exception,
}
response = http.HttpResponse(
loader.render_to_string(
'error.html',
context,
context_instance=template.RequestContext(request)
),
status=504
)
# maybe it'll be fixed in 5 minutes ? tell bots to come back
response['Retry-After'] = 5*60
return response
详细程度发生在 template/error.html:
{% extends 'site_base.html' %}
{% load i18n %}
{% block body %}
<h1>{% trans 'Oopsie' %} !</h1>
<p>
{% if error == 'ServerOverloaded' %}
{% blocktrans %}It's not your fault but our data provider is overloaded for the moment - and we don't have any cached version of the data you requested. Our techie has been notified but it's unlikely that he can do anything about it. Would you please try again later ?{% endblocktrans %}
{% endif %}
[.......]
{% if error == 'BetTooLateException' %}
{% with exception.bet.session as session %}
{% blocktrans %}You may not bet on {{ session }} because it has already started.{% endblocktrans %}
{% endwith %}
{% endif %}
{% endblock %}
尽量详细说明错误,尤其是避免给用户造成压力。想想那些会阅读你的错误信息的资深新手。在第一个异常的情况下,我认为很明显用户没有做错任何事情并且是暂时的。
在另一种情况下,BetTooLateException,好吧,我们可能只是捣毁了一个作弊者:)
顺便说一句,BetTooLateException 由模型抛出 - 来自 pre_save 信号。因此,根据我从您之前的问题中了解到的情况,这可能与您尝试做的事情非常相似。
【讨论】: