Python Flask Basics Character Builder Starting the Builder

Anders Axelsen
Anders Axelsen
3,470 Points

In the video at 2:01, I get this error: jinja2.exceptions.UndefinedError: 'function object' has no attribute 'get'

I have tried comparing my script with the script in the video some times. I do not, however, succeed in loading site. This occurred for the first time, when I was at 2:01. Maybe this will ease debugging a lengthier kind of script.

Kindly, Anders.

app.py:

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

app = Flask(__name__)



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




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


@app.route('/builder')
def builder():
    return render_template(
        'builder.html',
        saves=get_saved_data(),
        options=DEFAULTS
    )


@app.route('/save', methods=['POST'])
def save():
    response = make_response(redirect(url_for('builder')))
    data = get_saved_data()
    data.update(dict(request.form.items()))
    response.set_cookie('character', json.dumps(data))
    return response

app.run(debug=True, host='0.0.0.0', port=8000)

index.html:

{% 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 %}

options.py:

DEFAULTS = {
    "shirts": [
        "black",
        "green",
        "orange",
        "pink",
        "red",
        "teal",
        "purple"
    ],
    "pants": [
        "black",
        "blue",
        "green",
        "grey",
        "stars",
        "stripes",
        "tiger"
    ],
    "hat": [
        "black-baseball",
        "black-beanie",
        "bowler",
        "headband",
        "party",
        "pink-baseball",
        "pink-beanie"
    ],
    "glasses": [
        "optical-black",
        "optical-blue",
        "optical-purple",
        "optical-red",
        "optical-yellow",
        "sun-black",
        "sun-red"
    ],
    "footwear": [
        "sandal-pink",
        "sandal-purple",
        "shoes-black",
        "shoes-blue",
        "shoes-grey",
        "shoes-purple",
        "shoes-tiger"
    ],
    "colors": [
        "black",
        "purple",
        "blue",
        "green",
        "yellow",
        "orange",
        "red"
    ]
}

builder.html:

{% extends "layout.html" %}

{% block content %}
<!--Build Area -->
<form action="" method="POST" class="wrap no-top">
    <div class="grid-100 row">
        <div class="grid-30">
            <div class="title">
                <input type="text" name="name" value="{{ saves.get('name', '') }}">
            </div>
        </div>
        <div class="grid-70">
            <div class="colors">
                {% for color in options['colors'] $}
                    <input type="radio" id="{{ color }}" name="colors" value="{{ color }}"
                        {% if saves.get('color') == color %}checked{% endif %}>
                    <label for="{{ color }}"></label>
                {% endfor %}
                <button class="btn">Update</button>
            </div>
        </div>
        <div id="bear" class="grid-100">
            <div class="bear-body"><img src="/static/img/bear_body.svg" /></div>
            <div class="head"><img src="/static/img/bear_face.svg" /></div>
            <div class="nose"><img src="/static/img/bear_nose.svg" /></div>
        </div>
        <div class="items">
        </div>
    </div>
</form>

{% endblock %}

2 Answers

Anders Axelsen
Anders Axelsen
3,470 Points

Fixed! The get_saved_data() needed its ().

app.py line 22:

@app.route('/')
def index():
    return render_template('index.html', saves=get_saved_data())
Natalia Solomkina
Natalia Solomkina
1,594 Points

Had the same problem, thank you!

Dillon Reyna
Dillon Reyna
9,531 Points

Man - it's crazy how long two parenthesis kept me held up - thanks!