在Flask中使用Jinja2无法展示MongoDB集合数据
解决Jinja2模板无法显示MongoDB查询结果的问题
我一眼就看到问题所在啦——你遇到的是MongoDB Cursor对象的特性问题,咱们一步步来修复:
核心问题:Cursor对象只能被遍历一次
你在Flask代码里用movies.find()拿到的movie_list是一个MongoDB Cursor对象,这个对象的特点是只能被遍历一次。你已经用for tainia in movie_list循环打印了电影标题,这时候Cursor已经被"耗尽"了,再把它传给模板的时候,里面已经没有任何数据了,所以页面自然显示不出电影内容。
修复步骤
1. 将Cursor转换为列表
把查询结果转换成Python列表,这样数据就会被存下来,支持多次遍历:
# 把find的结果转成列表 movie_list = list(movies.find( {"actors": {"$in": [ request.form['actor'] ] } } ))
2. 调整调试用的循环(可选)
如果你需要保留打印调试的代码,现在遍历的是列表而不是Cursor,就不会影响传给模板的数据了:
movie_list = list(movies.find(...)) # 遍历列表打印,不会消耗数据源 for tainia in movie_list: print(tainia['title'])
3. 给模板加空数据提示+修正HTML结构(优化)
为了提升用户体验,可以在模板里判断如果没有找到电影就显示提示;另外你原来的actors循环没包裹<ul>标签,不符合HTML规范,顺便一起修正:
<body> <a href = "{{url_for('logout')}}"> Logout </a> {% if movie %} {% for document in movie %} <fieldset> <h2>Title : {{document.title}}</h2> <h2>Published : {{document.year}}</h2> <h2>Plot : {{document.plot}}</h2> <h2>Actors :</h2> <ul> {% for actor in document.actors%} <li> {{actor}} </li> {% endfor%} </ul> </fieldset> {% endfor %} {% else %} <p>没有找到该演员参演的电影哦</p> {% endif %} </body>
修改后的完整Flask代码
@app.route('/findmoviefromactor' , methods = ['GET' , 'POST']) def find_movie_from_actor(): if 'Email' in session and 'User' in session: user = session['User'] email = session['Email'] if request.method=='POST': # 查询特定演员参演的所有电影并转成列表 movie_list = list(movies.find( {"actors": {"$in": [ request.form['actor'] ] } } )) # 遍历列表打印调试 for tainia in movie_list: print(tainia['title']) # 打印每个电影标题 # 将电影列表传递给模板 return render_template('movie_details.html' , movie = movie_list) return render_template('movie-actor.html') else: return redirect(url_for('login'))
这样修改之后,模板就能正常显示电影内容啦~
内容的提问来源于stack exchange,提问作者Vasilis Skentos
相关产品推荐
相关产品推荐

