Forums

Jinja2 variables not being assigned in a for loop.

Hi all, I'm using Flask Appbuilder to develop an app for recording, tabulating and reporting votes for cars at a car show. I'm creating this on my local computer, pushing to Bitbucket and pulling to PythonAnywhere. It's worked just fine until now. In the code below I use a variable named currentClass to keep track of when the class of the cars changes. This works fine when running locally but when I deploy to PythonAnywhere the value of currentClass never changes from it's initial value of the empty string. The results set is being iterated over and the column values are being displayed in the table correctly. I've included the code xx{{currentClass}}xx{{currentVotes}}yy below just to dump the values.

Can anyone give me a clue about where to look for problems?

Thanks!

    <table class="table table-striped">
    <thead>
        <th>&nbsp;</th>
        <th>Class</th>
        <th>Votes</th>
        <th>Description</th>
        <th>Car #</th>
        <th>Owner</th>
        <th>Year</th>
        <th>Model</th>
    </thead>
    <tbody>
    {% set rowStyleFirstInClass = "border-top-style:solid;border-top-width:3px;border-top-color:black" %}
    {% set rowStyleHighlight = "color:#000000;background-color:#ffbbbb;" %}
    {% set rowStyleNormal = "color:#000000;background-color:#ffffff;" %}
    {% set rowStyle = rowStyleNormal %}
    {% set currentClass = "" %}
    {% set currentVotes = 0 %}
    {% for rec in results %}
        {% if rec[0] != currentClass %}
            {% set rowStyle = rowStyleFirstInClass %}
        {% else %}
            {% set rowStyle = rowStyleNormal %}
        {% endif %}
        <tr>
            {% if rec[0] == currentClass %}
                <td style="{{rowStyle}}">&nbsp;</td>
            {% else %}
                <td style="{{rowStyle}}"><i class="fa fa-arrow-right"/>xx{{currentClass}}xx{{currentVotes}}yy</td>
            {% endif %}
            {% for field in rec %}
            <td style = "{{rowStyle}}">{{field}}</td>
            {% endfor %}
        </tr>
        {% set currentClass = rec[0] %}
        {% set currentVotes = rec[1] %}
    {% endfor %}
    </tbody>
</table>

I can't see anything obvious that might cause that problem. Is currentVotes updating correctly?

Thanks for the reply. currentVotes is also not updating at all. currentVotes does stay at it's initial value of 0 when it's displayed so it appears to be in scope. Just to be sure my code is getting executed I've added visual indicators and they do show up as soon as I refresh the site and hit the page. Also, there are no errors in the error log. I'm stumped.

Ah, I think I've got it. If I'm understanding these docs correctly -- search for "Scoping behaviour" -- Jinja templates scope variables to the block where they're set -- essentially, each time through the loop, you have a completely new currentClass and currentVotes variables.

If that's the cause then I think the best option would probably be to generate appropriate values for the classes in Python code (where scoping behaviour is easier to understand :-) and then pass it in to the template.

Giles, Thanks for the work! I will read the docs and see what I can to do implement something that works. I do wonder why it works when I run it locally but not on PythonAnywhere. I'll post again when I've given it a try. Thanks again.

That is odd, certainly! Maybe a different Jinja version on PythonAnywhere versus locally? The docs I linked to are for the most recent version, though, and it would be odd if they'd reduced functionality in a newer version.

Might be worth checking, though -- perhaps a pip show jinja on both your local machine and on PythonAnywhere would help?