大型django项目中出现以下问题。我已经能够在一个小型模拟项目中复制这个问题(下面的代码)。
我正在尝试使用django messaging framework中的inclusion tag来在POST表单返回is_valid()时显示消息。这种方法也被用于另一个答案here(参见“最终更新”部分)。
问题是在POST后呈现页面时不会立即显示该消息。相反,该消息会显示您在其他地方导航的下一次时间,或者在收到POST响应后刷新页面。
我没有收到任何错误。除了延迟的消息显示外,一切似乎都正常运行。
这种方法的原因是因为我在多个应用程序中重复使用多个小表单,我需要将DRY主体用于GET和POST逻辑。这种方法非常有效 - 除了延迟'成功'消息显示的问题!
真的很感激任何反馈或帮助!
编辑:要清楚设置邮件的行在'my_template.py'中:
messages.add_message(context['request'], messages.SUCCESS, "Successfully added entry")
演示项目:
settings.py:
...
TEMPLATE_CONTEXT_PROCESSORS = (
"django.core.context_processors.request",
"django.core.context_processors.media",
"django.contrib.messages.context_processors.messages"
)
...
base_layout.html:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body>
{% for message in messages %}<div class="alert{% if message.tags %} alert-{{ message.tags }}{% endif %}" role="alert">{{ message }}</div>{% endfor %}
{% block content %}{% endblock %}
</body>
</html>
my_template.html:
<form action="" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
forms.py:
from django.forms.models import ModelForm
from app.models import ContactMessage
class ContactForm(ModelForm):
class Meta:
model = ContactMessage
fields = ['name']
的index.html:
{% extends "app/base_layout.html" %}
{% load my_template %}
{% block content %}
{% my_template %}
{% endblock %}
my_template.py:
from django import template
from django.contrib import messages
from app.forms import ContactForm
register = template.Library()
@register.inclusion_tag('app/my_template.html', takes_context=True)
def my_template(context):
if context['request'].method=='GET':
return { 'form':ContactForm() }
if context['request'].method=='POST':
form = ContactForm(context['request'].POST)
if not form.is_valid():
return { 'form': form }
form.save()
messages.add_message(context['request'], messages.SUCCESS, "Successfully added entry")
return { 'form':ContactForm() }
答案 0 :(得分:0)
消息传递框架通过中间件工作,您需要的是在同一请求/响应周期中通知发布的某种方式。你有手头的上下文变量,所以为什么不给它添加一个值:
if form.is_valid():
context['success']=True
else:
context['success']=False
然后在你的模板中:
{%if success %}<div>whoohoo!</div>{%endif%}
答案 1 :(得分:0)
根据Django的说法,消息排队等待渲染,直到它被渲染器清除。 this question
在您的情况下,您在渲染base.html中的{{ message }}
标记后添加邮件。因此,当您再次呈现base.html中的{{ message }}
时,系统会将您的消息存储到下一个视图中。
要解决此问题,您可以将{{ message }}
代码移至{% endblock %}
内容后面。另一种可能的解决方案是使用javascript从my_template.html或base.html的末尾添加{{ message }}
标记。