使用Jinja模板从数据库展示即将到来演出的代码问题排查
Jinja渲染即将到来演出功能排查与修正
现存问题点
- 路由查询逻辑无效:
Artist.query未调用.first()/get_or_404(),返回的是查询对象而非艺术家实例;查询演出时未过滤当前艺术家ID,会拉取全量演出数据;Python层循环未收集筛选结果,最终传给模板的r和upcoming_show仅为循环最后一次的临时值,完全无法用于渲染。 - 模型字段类型错误:演出
start_time定义为字符串类型,无法和datetime对象做准确的大小比较;seeking_talent、seeking_venue等布尔语义字段定义为字符串类型,后续判断易出错;字段名大小写不统一(Seeking_venue),不符合Python编码规范。 - 模板取值逻辑错误:演出模型本身没有
venue_name字段,直接调用会触发属性不存在错误;传入的upcoming_show是单个布尔值,无法对应每条演出的状态,循环内判断完全失效;未传入upcoming_shows_count对应的属性值,头部计数渲染会报错。
修正后的后端实现
先调整模型字段(存量数据库需配合Flask-Migrate做迁移,存量字符串格式时间需先转成datetime格式再改字段类型),再重写路由查询逻辑,直接在数据库层完成筛选,避免全量拉取数据后再循环过滤:
from datetime import datetime class Venue(db.Model): __tablename__ = 'venue' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String) city = db.Column(db.String(120)) state = db.Column(db.String(120)) address = db.Column(db.String(120)) phone = db.Column(db.String(120)) genres = db.Column(db.String(120)) image_link = db.Column(db.String(500)) facebook_link = db.Column(db.String(120)) website_link = db.Column(db.String(120)) seeking_talent = db.Column(db.Boolean, default=False) seeking_description = db.Column(db.String(120)) shows = db.relationship( 'Shows', backref='venue', lazy='joined', cascade='all, delete') class Artist(db.Model): __tablename__ = 'artist' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String) city = db.Column(db.String(120)) state = db.Column(db.String(120)) phone = db.Column(db.String(120)) genres = db.Column(db.String(120)) image_link = db.Column(db.String(500)) facebook_link = db.Column(db.String(120)) website_link = db.Column(db.String(120)) seeking_venue = db.Column(db.Boolean, default=False) seeking_description = db.Column(db.String(120)) shows = db.relationship( 'Shows', backref='artist', lazy='joined', cascade='all, delete') class Shows(db.Model): __tablename__ = 'shows' id = db.Column(db.Integer, primary_key=True) artist_id= db.Column(db.Integer, db.ForeignKey('artist.id'), nullable = False) venue_id= db.Column(db.Integer, db.ForeignKey('venue.id'), nullable = False) start_time = db.Column(db.DateTime, nullable=False) @app.route('/artists/<int:artist_id>') def show_artist(artist_id): artist = Artist.query.get_or_404(artist_id) current_time = datetime.now() # 联表查询当前艺术家未开始的演出,直接返回演出+对应场地的结构化数据 upcoming_shows = db.session.query(Shows, Venue)\ .join(Venue, Shows.venue_id == Venue.id)\ .filter( Shows.artist_id == artist_id, Shows.start_time > current_time ).all() # 绑定演出计数字段供模板头部使用 artist.upcoming_shows_count = len(upcoming_shows) return render_template('pages/show_artist.html', artist=artist, upcoming_shows=upcoming_shows)
修正后的模板代码
直接遍历后端筛选好的即将到来演出列表,不需要在模板层做状态判断:
<section> <h2 class="monospace">{{ artist.upcoming_shows_count }} Upcoming {% if artist.upcoming_shows_count == 1 %}Show{% else %}Shows{% endif %}</h2> <div class="row"> {% for show, venue in upcoming_shows %} <div class="col-sm-4"> <div class="tile tile-show"> <img src="{{ venue.image_link }}" alt="Show Venue Image" /> <h5><a href="/venues/{{ venue.id }}">{{ venue.name }}</a></h5> <h6>{{ show.start_time|datetime('full') }}</h6> </div> </div> {% endfor %} </div> </section>
提示:时间筛选、关联查询尽量在数据库层完成,相比把全量数据拉到Python内存再循环过滤,性能会有明显提升,数据量越大差异越明显。
内容的提问来源于stack exchange,提问作者JOSEPH AKPAN
相关产品推荐
相关产品推荐

