-->

Django messaging framework messages not making it

2019-09-16 12:00发布

问题:

I have some "save" code that sets a success message using the Django messaging framework upon successful creation of a record, then does a redirect back to the main 'application_update' view. I'm having trouble determining why these messages are not making it thru the redirect. The messaging seems to work just fine when doing a "render_to_response", but not when doing a "redirect".

function snippet (if POST) in views.py:

if ovrd_form.is_valid():
    fields = {'application': ovrd_form.cleaned_data['application'],
              'course': ovrd_form.cleaned_data['course'],
              * other field/values *
             }
    try:
        overrides = Overrides(**fields)
        overrides.save()
        success_msg = 'Override creation was successful.'
        create_message(request, success_msg, 'success')
    except Exception, exception:
        return HttpResponse('Error: ' + str(exception))

    return redirect('application_update', app_id=app_id)

create_message() function:

from django.contrib import messages

def create_message(request, msg, msg_type):
    """ build a message & sets the correct message.type """
    if msg_type == 'error':
        django.contrib.messages.error(request, msg)
    elif msg_type == 'warning':
        django.contrib.messages.warning(request, msg)
    elif msg_type == 'success':
        django.contrib.messages.success(request, msg)
    elif msg_type == 'info':
        django.contrib.messages.info(request, msg)
    elif msg_type == 'debug':
        django.contrib.messages.debug(request, msg)

all templates inherit this piece of code:

{% if messages %}
    {% for message in messages %}
        {% comment %}force -danger if error type for bootstrap css class{% endcomment %}
        {% if message.tags == 'error' %}
            <div class="alert alert-danger">
        {% else %}
            <div class="alert alert-{{ message.tags }}">
        {% endif %}
            <button type="button" class="close" data-dismiss="alert">&times;</button>
            <span>{{ message }}</span>
            </div>
    {% endfor %}
{% endif %}

Any help would be very much appreciated.

回答1:

We use a function similar to the one below to preserve messages after one or more redirects:

# Preserve any error messages... ie. if a redirect results in another
# redirect.  

from django.contrib import messages

def preserve_error_messages( request ):
    mstore = messages.get_messages( request )
    for m in mstore:
        messages.add_message( request, m.level, m.message, extra_tags = m.extra_tags )
    return

EDIT: This is equivalent to preventing messages from being cleared/expired: https://docs.djangoproject.com/en/1.4/ref/contrib/messages/#expiration-of-messages



回答2:

You need to use a RequestContext in your destination view in order to pass the message into the template. The easiest way to do that is to use the render shortcut rather than render_to_response:

return render(request, 'view.html', {'form': ovrd_form})

Note that the first parameter is the request object.



回答3:

Eureka! Sort of. It would seem that I may have either needed to reboot my VM session (can’t see how this would be it, but stranger things…) or I needed to clear my browser cache (session parms).

Reboot of VM: from time to time I experience internal clock issues with my Vagrant VM box which results in Oauth discrepancies, which in turn causes my REST API calls to fail, which is corrected once I reboot the SSH session and/or vagrant halt and vagrant up my VM. How does this tie in to my messaging problem? Not sure it does, only stating that I may be getting some VM corruption over time that could affect more than what I’m aware of. Lesson learned for me is to reboot the VM anytime I have weirdness that just doesn’t add up.

  • Note: I don’t shutdown my VM or computer every night, and I do carry it home. This means it has to make contact with different wifi networks, and that causes me to have to restart my SSH terminal often. The VM is therefore run for days…or at least till it gets buggy.

Clear my cache: I made myself forget about this problem over the weekend and when I started working on it this morning…walla! All is well. I had to do the VM thing stated above before trying to reload the page (to get the auths problem fixed), so I’m not certain if the correction came from that or just because my session parms likely expired.

Thanks to @TravisD & @DanielRoseman for the help!



回答4:

Added below in local_settings.py and it is working.

MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'

Know more here.