Is there an equivalent to Rails’ “flash” messages

2019-02-23 09:27发布

Ruby on Rails has a way that you can set a message, like flash[:notice] and flash[:error, that the user will see at the next opportunity. It’s especially useful for things like notifying the user of failure to log in, etc., when they are redirected (e.g. back to a sign-in page).

Is there a canonical or common way to achieve this on Google App Engine (Python API)? (Assume Django is not being used.)

5条回答
混吃等死
2楼-- · 2019-02-23 09:47

Yes, look at this function get_flashes(key='_flash')[source] in this object: class webapp2_extras.sessions.SessionDict(container, data=None, new=False)[source]

Returns a flash message. Flash messages are deleted when first read. Parameters: key – Name of the flash key stored in the session. Default is ‘_flash’. Returns:
The data stored in the flash, or an empty list.

查看更多
爷的心禁止访问
3楼-- · 2019-02-23 09:48

What do you think about extending a template and setting the "flash" parameter to the template?

for example, base template :

<html... bla blah ...
<body ... bla blah
{% if flash %} {{flash}} {% endif %}
<!-- more html here -->
{% block content %}

your dynamic block here...

{% endblock %}

now at every template

{% extends "base_template.html" %}
{% block content %}
    {% if object %} success to edit : {{object.title }} {% endif %}
{% endblock %}

your handler should pass flash param to the template, it will be used at the base template.

查看更多
霸刀☆藐视天下
4楼-- · 2019-02-23 10:00

Webapp framework, the simple web application framework that ships with GAE, does not provide something like that.

One cool framework built specifically for Google App Engine that offers Flash messages is Tipfy.
Have a look to tipfy.ext.session module:

set_flash(data, key=None, backend=None, **kwargs)

Sets a flash message. Flash messages are deleted when first read.

查看更多
5楼-- · 2019-02-23 10:07

Well, webapp2 does have:

def add_flash(self, value, level=None, key='_flash'):

and:

def get_flashes(self, key='_flash'):

That stores your messages and deletes them when read. To show them to the user, you just need to set a variable in your base request handlers render_template method. Something like this:

def render_template(self, template, context=None):
    context = context or {}

    extra_context = {
        'uri_for': self.uri_for,
        'flashes': self.session.get_flashes(),
        'user': self.current_user,
    }

    # Only override extra context stuff if it's not set by the template:
    for key, value in extra_context.items():
        if key not in context:
            context[key] = value

    rendered = self.jinja2.render_template(template, **context)
    self.response.write(rendered)

And in your template, use the 'flashes' variable to display your messages however you like.

Docs here: http://code.google.com/p/webapp-improved/source/browse/webapp2_extras/sessions.py?r=9c1ec933be7c3d8c09c9bf801ebffe2deeb922e0#127

Live example over here: https://simpleauth.appspot.com/

and the example's source: http://code.google.com/p/gae-simpleauth/source/browse/example/handlers.py

By the way, great work with simpleauth Alex!

查看更多
孤傲高冷的网名
6楼-- · 2019-02-23 10:11

I like llazzaro's advice regarding templates.

The other half to the story is being able to maintain the flash message between requests.

  1. If you are dealing with sessions, stick the message in the session.

  2. If you don't have session support, you'll have to create use a cookie.

    Cookie caveats:

    • It’s surprisingly hard to set cookies in GAE because you basically have to set the header yourself. (Correct this if there is an API built in to GAE to set cookies; it's a community wiki). Beware of encoding and other limitations (semicolons indicate end of your cookie value). Find a well-written function to write cookies and use it.
    • Be aware of browser cookie length limits
    • If you are sending a preset message, consider just setting a unique identifier for the message in the cookie instead of the actual message. You won't have issues with length or encoding!
    • If your message is variable, one possible workaround is just like the above bullet point, but instead of preset messages, push a datastore object when setting a message, write its identifier to a cookie, and when displaying the message, look it up in the datastore and then wipe the cookie.

Regardless, when you display flash messages, immediately clear the message from the session or cookie.

查看更多
登录 后发表回答