In a django view, how do I show errors raised by the model?
在django视图中,如何显示模型引发的错误?
This is a follow up question for this quesiton.
这是这个问题的后续问题。
1 个解决方案
#1
1
Actually Django makes it easier than stealing a piece of cake from a 1 year old baby. All you need is to write a process_exception() function in a class that should be added to MIDDLEWARE_CLASSES. Based on that, you can take error handling pretty far.
实际上,Django比从1岁婴儿那里偷一块蛋糕更容易。您只需要在应该添加到MIDDLEWARE_CLASSES的类中编写process_exception()函数。基于此,您可以进行相当多的错误处理。
You can create a middleware.py file in your project root. Then add it to settings:
您可以在项目根目录中创建middleware.py文件。然后将其添加到设置:
MIDDLEWARE_CLASSES = [
# [....] all other middlewares above
'middleware.ExceptionMiddleware',
]
If you have the great django-sentry, you probably only want to handle some exceptions, and leave the rest to django-sentry. In that case, you can create such a setting:
如果你有伟大的django-sentry,你可能只想处理一些例外,剩下的就是django-sentry。在这种情况下,您可以创建这样的设置:
EXCEPTION_MIDDLEWARE_HANDLES = [
'ServerOverloaded',
# [...] other exception class names that you want to handle in your middleware
'BetTooLateException',
]
I'm going to show you an example middleware that implements process_request() and handles exceptions which class names are in EXCEPTION_MIDDLEWARE_HANDLES. It might not exactly suit your need, but it's really trivial to adapt to your own needs
:
我将向您展示一个实现process_request()的示例中间件,并处理类名在EXCEPTION_MIDDLEWARE_HANDLES中的异常。它可能不完全符合您的需求,但适应您自己的需求真的微不足道:
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
Verbosity takes place in template/error.html:
详细程度发生在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 %}
Try to detail the errors as much as possible and especially avoid to stress the user. Think of the senior neophytes whom will read your error message. In the case of the first exception, I think it's pretty clear that the user didn't do anything wrong and that it's temporary.
尽量详细说明错误,尤其要避免给用户带来压力。想想那些会阅读你的错误信息的高级新手。在第一个例外的情况下,我认为很明显用户没有做错任何事情并且这是暂时的。
In the other case, BetTooLateException, well we probably just busted a cheater :)
在另一种情况下,BetTooLateException,我们可能只是破坏了骗子:)
And BTW, BetTooLateException is thrown by the model - from a pre_save signal. So that's probably quite similar to what you're trying to do according to what I understand from your previous questions.
BTW,BetTooLateException由模型抛出 - 来自pre_save信号。因此,根据我之前的问题所理解的内容,这可能与您尝试做的很相似。
#1
1
Actually Django makes it easier than stealing a piece of cake from a 1 year old baby. All you need is to write a process_exception() function in a class that should be added to MIDDLEWARE_CLASSES. Based on that, you can take error handling pretty far.
实际上,Django比从1岁婴儿那里偷一块蛋糕更容易。您只需要在应该添加到MIDDLEWARE_CLASSES的类中编写process_exception()函数。基于此,您可以进行相当多的错误处理。
You can create a middleware.py file in your project root. Then add it to settings:
您可以在项目根目录中创建middleware.py文件。然后将其添加到设置:
MIDDLEWARE_CLASSES = [
# [....] all other middlewares above
'middleware.ExceptionMiddleware',
]
If you have the great django-sentry, you probably only want to handle some exceptions, and leave the rest to django-sentry. In that case, you can create such a setting:
如果你有伟大的django-sentry,你可能只想处理一些例外,剩下的就是django-sentry。在这种情况下,您可以创建这样的设置:
EXCEPTION_MIDDLEWARE_HANDLES = [
'ServerOverloaded',
# [...] other exception class names that you want to handle in your middleware
'BetTooLateException',
]
I'm going to show you an example middleware that implements process_request() and handles exceptions which class names are in EXCEPTION_MIDDLEWARE_HANDLES. It might not exactly suit your need, but it's really trivial to adapt to your own needs
:
我将向您展示一个实现process_request()的示例中间件,并处理类名在EXCEPTION_MIDDLEWARE_HANDLES中的异常。它可能不完全符合您的需求,但适应您自己的需求真的微不足道:
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
Verbosity takes place in template/error.html:
详细程度发生在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 %}
Try to detail the errors as much as possible and especially avoid to stress the user. Think of the senior neophytes whom will read your error message. In the case of the first exception, I think it's pretty clear that the user didn't do anything wrong and that it's temporary.
尽量详细说明错误,尤其要避免给用户带来压力。想想那些会阅读你的错误信息的高级新手。在第一个例外的情况下,我认为很明显用户没有做错任何事情并且这是暂时的。
In the other case, BetTooLateException, well we probably just busted a cheater :)
在另一种情况下,BetTooLateException,我们可能只是破坏了骗子:)
And BTW, BetTooLateException is thrown by the model - from a pre_save signal. So that's probably quite similar to what you're trying to do according to what I understand from your previous questions.
BTW,BetTooLateException由模型抛出 - 来自pre_save信号。因此,根据我之前的问题所理解的内容,这可能与您尝试做的很相似。