How to reference dictionary value without iterating in Jinja2 template?

3848 views python
7

Am attempting to reference a specific dictionary value in my Jinja2 template, but it seems it only allows me to reference with integer indices instead of the named key.

Here is my Flask/Python3.6 code:

data_dict = {"saved_selections": {}, "records": 0}
for row in cursor.fetchall():
    data_dict["saved_selections"].update({"question" + row[1]: row[2]})

The data in row is 3 columns (confirmed). Index 1 is an ID field, and index 2 is the value I want to store.

In my html template, I have tried:

"data_dict" is returned in a function and stored in variable called "data" which is returned in the "render_template" function.

<option value="Not Reviewed" {% if data[0][0][2]=="Not Reviewed" %} selected="selected"{% endif %}>Not Reviewed</option>

and:

<option value="Not Reviewed" {% if data['saved_selections']['question1'][2]=="Not Reviewed" %} selected="selected"{% endif %}>Not Reviewed</option>

When I attempt the named key way, I get the error:

jinja2.exceptions.UndefinedError: dict object has no element 'saved_selections'

Here is some of the sample data returned in my query if useful:

LatestRound ReviewItemTaskID    ReviewItemValue
6           2                   Yes
6           3                   Yes
6           4   
6           5                   No - Provided Training
6           6                   No - Requested Update

I'm ultimately just trying to return a dictionary that has each row's values in it (under a single key named "saved_selections"), another key named "records" that will store the total rows returned, and then be able to reference them in my template without needing to iterate with a for loop.

EDIT: thought it would be helpful to add what I'm wanting my data to look like:

data_dict = {
    "saved_selections": {
        "question1": "Yes",
        "question2": "Not Reviewed",
        "question3": "No - Provided Training"
    },
    "records": 3
}

EDIT 2: Here is the view function where data is defined and returned:

@app.route("/main", methods=["POST"])
def main_page():
    data = (c.getReviewData(location=request.form['location'])
    return render_template("main.html", data=data, location=location)

answered question

Python dictionaries are unordered. They do not have set indices. You access them by their key to get the value. If you store data_dict as a list or OrderedDict instead of a dict then you can access it by its indices since it has order. Also in your html template you are using data instead of data_dict it seems.

Yes - sorry, I will update OP. data_dict is returned in a function and stored in variable called "data" which is returned in the "render_template" function.

Is your value stored in question2 always the value you want to be doing the comparison on in the template?

for that particular select dropdown, yes, "question2"s value is what I will always use for that comparison. For the "question3" select dropdown, I would use the value in "question3" key for the comparison.

Then you should be accessing the data dict like data['saved_selections']['question2']=='Not Reviewed' in your template. Because whatever you are doing with the [2] at the end of your accessing the value is not correct.

1 Answer

12

There is likely something wrong with your data_dict. Perhaps your overwriting it somewhere, or retuning the wrong dict to jinja.

First this

<option value="Not Reviewed" {% if data['saved_selections']=="banana" %} selected="selected"{% endif %}>Not Reviewed</option>

In combinations with this render_template

return render_template('test.html', data={'saved_selections': 'banana'})

To ensure that your dict is correct.

But we need to see the entire flask route in order to find the issue here.

posted this

Have an answer?

JD

Please login first before posting an answer.