How can I reload the for loop in flask jinja2?

I’m having a trouble with using for loop in flask jinja2. This is what I did.

mongodb collection

firstCollection = {{"company":"apple"},{"company":"tesla"},{"company":"google"}}
secondCollection = {{"number":"1"},{"number":"2"},{"number":"3"}}

run.py

import flask
import pymongo
from flask import abort, Flask, render_template
from flask_pymongo import PyMongo


app = Flask(__name__)
app.config["MONGO_URI"] = "mongodb://localhost:27017/mrstock" 
mongo = PyMongo(app)

@app.route("/")
def test():

    coll1 = mongo.db.firstCollection
    coll2 = mongo.db.secondCollection

    coll1Datas = coll1.find({})
    coll2Datas = coll2.find({})

    return render_template("test.html",coll1Datas=coll1Datas,coll2Datas=coll2Datas)


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

test.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>


    {% for coll1 in coll1Datas %}
            {{coll1.company}}
            {% for coll2 in coll2Datas %}
                {{coll2.number}}
            {% endfor %}
    {% endfor %}
</body>
</html>

the result is looking like this

apple 123 tesla google

this is for loop in for loop so, I was expecting like

apple 123 tesla 123 google 123

why the second loop inside the first loop only working one time? I did several test, and I think after for loop, jinja2 do not have data information anymore. How can I use data ‘for loop’ again and again which send from flask? Thank you for your support!

Hi @JJ_Lee! Great question - this is a problem encountered by many Python developers!

A PyMongo find call returns an iterable - which is something that can be looped over with a for loop. This has the advantage that the data downloads in chunks as you as you loop through the results - which means you don’t need to store the whole result in memory! This does mean that you can only loop through it once, as you’ve discovered.

The solution is to add all the results to a list - which may use more memory, because all the results are now loaded into memory at one time - but it means you can loop through the list multiple times. Fortunately, this is quite straightforward in Python - you wrap the iterable with list, like this:

coll1Datas = list(coll1.find({}))
coll2Datas = list(coll2.find({}))

I hope this helps! If you want to learn more about loops and iterables in Python, you should check out this talk by my friend Trey Hunner.

2 Likes

Oh My~! really really thank you!! I couldn’t find solution and had almost two days spent for this problem. Really thank you!! Have a great day :slight_smile:

Sincerely,
from Korea.

2 Likes

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.