Python Flask Basics Character Builder Cookies

Brian Patterson
Brian Patterson
19,585 Points

jinja2.exceptions.UndefinedError

I have the following code in my app.py file.

import json
from flask import (Flask, render_template, redirect,
            url_for, request, make_response)

app = Flask(__name__)


def get_saved_data():
    try:
        data = json.loads(request.cookies.get('character'))
    except TypeError:
        data = {}
    return data

@app.route('/')
def index():
    data = get_saved_data
    return render_template('index.html', saves=data)


@app.route('/save', methods=['POST'])
def save():
    response = make_response(redirect(url_for('index')))
    data = get_saved_data() #You have this information already stored
    data.update(dict(request.form.items()))#Update that information
    response.set_cookie('character', json.dumps(data))# the send it back.
    return response

if __name__ == '__main__':
    app.run(debug=True)

Now in my index file I have the following:

{% extends "layout.html" %}
{% block content %}
<!--Enter Name -->
<div class="enter-name">
    <div class="grid-100">
        <img src="/static/img/bear_avatar.svg" class="bear-avatar" />
    </div>
    <div class="grid-100">
        <form action="{{ url_for('save') }}" method="POST">
            <label>Name your bear</label>
            <input type="text" name="name" value="{{ saves.get('name','')}}" autofocus>
            <input type="submit" value="Let's build it!">
        </form>
    </div>
</div>
{% endblock %}

The problem I am getting is when I save the file I get the following error:

jinja2.exceptions.UndefinedError
jinja2.exceptions.UndefinedError: 'function object' has no attribute 'get'

[MOD: added ```python formatting -cf]

Adam Cameron
Adam Cameron
Python Web Development Techdegree Graduate 16,730 Points

Did you ever figure this out? I'm getting this exact error too and our code matches - wonder if Kenneth Love or Chris Freeman might have an answer?

1 Answer

Adam Cameron
Adam Cameron
Python Web Development Techdegree Graduate 16,730 Points

Oh. I figured it out. In your index() view you need to add a pair of parentheses. The language to describe exactly why this isn't working isn't coming to me but I know it has to do with calling a function object versus the output of a function itself. Maybe our buds Kenneth Love and Chris Freeman can further explain.

Chris Freeman
Chris Freeman
Treehouse Moderator 56,817 Points

You've got it! In the statement:

    data = get_saved_data

data is getting assigned the function itself, not the results of the execution of the function get_saved_data. To get the execution, parens must be present.

In Python, functions can be passed around like any other variable. This is especially useful in python functions like map and filter that take a function as the first argument.