flaskjinja2ponyorm

jinja2.exceptions.UndefinedError: 'flask.ctx._AppCtxGlobals object' has no attribute 'words'


I currently have a before_request that stores words in the g variable.
I then have a index.html that I extend in child templates. But for some reason it doesn't read the gloabl g variable sometimes.

This is the function to set the g

@app.before_request
def setup_words_and_ratings():
    if request.method == "GET":
        lang = request.args.get('lang') or session.get('lang')
        if not lang:
            try:
                lang = request.headers.get('Accept-Language').split(",")[0][:2]
                if len(lang) != 2:
                    lang = "en"
            except:
                lang = "en"
        cache = red.get("%s%s" % (lang,version))
        if cache:
            words = pickle.loads(cache)
        else:
            words = models.Translation.translation_as_dict(lang)
            red.set("%s%s" % (lang,version), pickle.dumps(words))
            red.expire("%s%s" % (lang,version), 60 * 60 * 24 * 30)
        g.words = words
        g.words['lang'] = lang
        session['lang'] = lang

But I get this error

[2019-08-01 21:22:54 +0000] [15435] [ERROR] Error handling request /ppt-pdf
Traceback (most recent call last):
  File "/home/www/pdfenv/lib/python3.6/site-packages/gunicorn/workers/sync.py", line 135, in handle
    self.handle_request(listener, req, client, addr)
  File "/home/www/pdfenv/lib/python3.6/site-packages/gunicorn/workers/sync.py", line 176, in handle_request
    respiter = self.wsgi(environ, resp.start_response)
  File "/home/www/pdfenv/lib/python3.6/site-packages/flask/app.py", line 2309, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/www/pdfenv/lib/python3.6/site-packages/pony/utils/utils.py", line 37, in pony_wrapper
    return caller(func, *args, **kwargs)
  File "/home/www/pdfenv/lib/python3.6/site-packages/pony/orm/core.py", line 472, in new_func
    result = func(*args, **kwargs)
  File "/home/www/pdfenv/lib/python3.6/site-packages/flask/app.py", line 2295, in wsgi_app
    response = self.handle_exception(e)
  File "/home/www/pdfenv/lib/python3.6/site-packages/flask/app.py", line 1741, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/www/pdfenv/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/home/www/pdfenv/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/www/pdfenv/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/www/pdfenv/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/www/pdfenv/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/home/www/pdfenv/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/www/pdfenv/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/www/pdfto/app.py", line 269, in ppttopdf
    return render_template('ppttopdf.html')
  File "/home/www/pdfenv/lib/python3.6/site-packages/flask/templating.py", line 135, in render_template
    context, ctx.app)
  File "/home/www/pdfenv/lib/python3.6/site-packages/flask/templating.py", line 117, in _render
    rv = template.render(context)
  File "/home/www/pdfenv/lib/python3.6/site-packages/jinja2/asyncsupport.py", line 76, in render
    return original_render(self, *args, **kwargs)
  File "/home/www/pdfenv/lib/python3.6/site-packages/jinja2/environment.py", line 1008, in render
    return self.environment.handle_exception(exc_info, True)
  File "/home/www/pdfenv/lib/python3.6/site-packages/jinja2/environment.py", line 780, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/www/pdfenv/lib/python3.6/site-packages/jinja2/_compat.py", line 37, in reraise
    raise value.with_traceback(tb)
  File "/home/www/pdfto/templates/ppttopdf.html", line 1, in top-level template code
    {% extends 'index.html' %}
  File "/home/www/pdfto/templates/index.html", line 2, in top-level template code
    <html lang="{{ g.words['lang'] }}">
  File "/home/www/pdfenv/lib/python3.6/site-packages/jinja2/environment.py", line 411, in getitem
    return obj[argument]
jinja2.exceptions.UndefinedError: 'flask.ctx._AppCtxGlobals object' has no attribute 'words'

In the index I call the g variable like so <html lang="{{ g.words['lang'] }}">

Am I missing something with jinja environments?


Solution

  • Looking at your code, you are making the variables only available in case of GET method. You should probably remove that condition, so it is available even in case of POST requests as well

    @app.before_request
    def setup_words_and_ratings():
        lang = request.args.get('lang') or session.get('lang')
        if not lang:
            try:
                lang = request.headers.get('Accept-Language').split(",")[0][:2]
                if len(lang) != 2:
                    lang = "en"
            except:
                lang = "en"
        cache = red.get("%s%s" % (lang,version))
        if cache:
            words = pickle.loads(cache)
        else:
            words = models.Translation.translation_as_dict(lang)
            red.set("%s%s" % (lang,version), pickle.dumps(words))
            red.expire("%s%s" % (lang,version), 60 * 60 * 24 * 30)
        g.words = words
        g.words['lang'] = lang
        session['lang'] = lang