如何在 Django 的自定义 404 错误模板中显示传递给 Http404 的消息?
Posted
技术标签:
【中文标题】如何在 Django 的自定义 404 错误模板中显示传递给 Http404 的消息?【英文标题】:How to display the message passed to Http404 in a custom 404 Error template in Django? 【发布时间】:2010-12-09 22:06:30 【问题描述】:我有一个正在 django 中工作的项目。在很多情况下,我:
raise Http404("this is an error")
它为我创建了一个漂亮的 404 页面,上面写着错误消息“这是一个错误”。
我现在想创建一个自定义错误页面并让它仍然显示消息,但我不知道如何。
我确定这只是我需要添加到自定义 404 模板中的模板变量,但我找不到任何文档。
【问题讨论】:
您是否找到了将“这是一个错误”消息输入自定义 404 处理程序的方法? @Alasdair,nbv4,我真的很感激你的帮助。 @marianobianchi 我错误地说可以使用自定义 404 处理程序来实现这一点,但实际上不可能。有一个pull request 需要更改,但被拒绝了。想了想,我同意这个决定。我认为最好使用 Euribates 建议的消息框架,或者呈现自定义模板并返回状态 404。如果您在默认的 404 模板中包含异常消息,则存在向最终用户显示不合适的错误消息的风险。 【参考方案1】:从 Django 1.9 开始,异常被传递给 page_not_found
视图,当您引发 Http404
时运行该视图。错误的表示被传递给模板,您可以将其包含在模板中:
exception
在早期版本中,异常不会传递给 page_not_found
视图,因此没有简单的方法将异常消息包含在模板中。
一种可能性是使用@Euribates 在他们的回答中建议的消息框架。另一个是渲染模板并在视图中返回 404 状态码,而不是引发 Http404
。
【讨论】:
exception
仅在 DEBUG
设置为 True
时呈现视图中设置的任何自定义消息。如果DEBUG = False
,那么404.html中使用的 exception
只会渲染“Http404”。
@DanSwain 不确定我是否理解您的评论。如果 DEBUG
是 True
则 Django 显示黄色页面未找到页面。如果DEBUG
是False
,则默认视图会尝试显示来自异常的消息。如果您看到Http404
,则可能在没有消息的情况下引发了异常,例如raise Http404
.
@Alasdair,这是我正在运行的代码:try:
topic = Topic.objects.get(slug=slug)
except Topic.DoesNotExist:
raise Http404("Topic does not exist")
当我将DEBUG
设置为True
,然后“主题不存在”显示在黄色错误页面中,但是如果我将DEBUG
设置为False
,那么标准404.html模板中的 exception
会呈现“Http404”,而不是“主题不存在”。
我刚刚用默认的page_not_found
404 处理程序仔细检查了 exception
,它肯定会在Django 2.0 中显示异常消息。如果您仍然无法使其正常工作,请提出一个包含足够详细信息的新问题以重现该问题。
如果您的消息被替换为默认消息(此处为 Http404),可能是因为您使用的是gettext_lazy()
而不是gettext()
【参考方案2】:
还有另一种方法。 page_not_found
处的代码使用RequestContext
;这意味着您可以访问由settings.py
中的TEMPLATE_CONTEXT_PROCESSORS
条目中定义的所有上下文处理器定义的所有变量。默认值包括django messages framework。
因此,例如,您可以使用messages.error
定义要显示的消息,并使用messages
变量在模板中显示消息。
换句话说,你可以这样写你的视图:
from django.contrib import messages
from django.http import Http404
from django.template import RequestContext
def my_view(request):
# your code goes here
if something_horribly_wrong_happened():
messages.error(request, 'Somethig horribly wrong happened!')
raise Http404("It doesn't mind whatever you put here")
else:
return render_to_response(
'template.html',
RequestContext(request, locals()),
)
在您的 404.html 模板中,您应该编写如下内容:
% if messages %
<ul class="messages">
% for message in messages %
<li> message </li>
% endfor %
</ul>
% endif %
它有点复杂,但它的优点是可以发送多条消息,甚至可以使用不同类型的消息(警告、调试、信息、错误等...)您可以阅读有关 django 消息框架的更多信息这里:The messages framework | Django Documentation。
【讨论】:
嗨,你能看看我的问题吗? ***.com/questions/66900041/…【参考方案3】:我有更简单的解决方案
只需编写中间件,它会将您的错误文本放入某个请求变量中。看例子
from django.http.response import Http404
class Error404Middleware(object):
def process_exception(self, request, exception):
if isinstance(exception, Http404):
request.error_404_message = exception.message
在 404.html 中
request.error_404_message
【讨论】:
【参考方案4】: exception
从 1.9.6 开始,消息传递给:
raise Http404('msg')
可从templates/404.html
获得:
exception
来源:https://github.com/django/django/blob/1.9.6/django/views/defaults.py#L20
【讨论】:
嗨,你能看看我的问题吗? ***.com/questions/66900041/… @kd12345 感谢 ping,但恐怕我已经很久没有接触 Django 了 :-( 你介意我问一下你在 python 中使用什么 ORM 吗? @kd12345 我做的唯一 Python webdev 是 2014 年的一点 Django,所以我只是使用他们内置的 ORM。我认为这是体面的。现在我再次选择 webdev,但我正在查看是否有任何像样的 Node.js Web 框架可以更轻松地进行服务器端渲染。虽然有一段时间。 我刚刚开始学习 Django,因此我的问题可能看起来很业余。我实际上是从 Node.js 转移过来的。如果您使用 SQL,Sequelize 是一个非常强大的 ORM。我真的发现它使用起来非常简单流畅。以上是关于如何在 Django 的自定义 404 错误模板中显示传递给 Http404 的消息?的主要内容,如果未能解决你的问题,请参考以下文章
我的自定义 Django 模板过滤器但没有任何其他过滤器的“无效过滤器”错误
“模板语法错误:过滤器无效:”;基于 django 文档的自定义 django 模板过滤器损坏,但模板标签有效
如何在我的自定义小部件模板中包含内置的 django 小部件模板?