Delayed display of message from within an inclusion tag

妖精的绣舞 提交于 2019-12-25 09:35:04

问题


The following problem is occurring in a large django project. I've been able to replicate the issue in a small mock-up project (code below).

I am trying to use the django messaging framework within an inclusion tag to display a message when a POST'ed form returns is_valid(). This approach has also been used in an another answer here (see 'final update' section).

The problem is that the message is not immediately displayed when the page is rendered after the POST. Instead the message appears the next time you navigate elsewhere or refresh the page after the POST response is received.

I am not receiving any errors. Everything appears to be operating normally, except for the delayed message display.

The reason for this approach is because I'm reusing multiple small forms across multiple apps and I need to use DRY principals for the GET and POST logic. This approach works perfectly - except for the issue with the delayed 'success' message display!

Really appreciate any feedback or assistance!

EDIT: To be clear the line which sets the message is in 'my_template.py':

messages.add_message(context['request'], messages.SUCCESS, "Successfully added entry")

The Demo Project:

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() }

回答1:


The messaging framework works through middleware, what you need is some way of informing the posting in the same request/response cycle. You have the context variable at hand, so why not add a value to it:

if form.is_valid():
    context['success']=True
else:
    context['success']=False

Then in your template:

{%if success %}<div>whoohoo!</div>{%endif%}



回答2:


According to Django, the messages are queued for rendering until it is cleared by renderer. (reference)

In your case, you are adding messages after {{ message }} tags in base.html has been rendered. So your message is stored until your next view when {{ message }} in base.html is rendered again.

To solve this, you can move your {{ message }} tags behind {% endblock %} of content. Another possible solution is to use javascript to append {{ message }} tags either from my_template.html or from end of base.html.



来源:https://stackoverflow.com/questions/28124348/delayed-display-of-message-from-within-an-inclusion-tag

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!