CS50 Finance项目:Jinja循环渲染时行值被最后一条数据覆盖问题
逐行股价覆盖问题修复说明
问题根因
- 后端循环全程只操作同一个全局
portfolio字典:每轮循环会先通过update(row)把持仓的名称、代码、股数覆盖到字典上,再给固定键price、total_value赋值,没有给每只股票保存独立的数据空间,所有遍历结果最终都会被最后一轮循环的Oracle持仓覆盖 - 模板固定读取全局
portfolio的单条值,没有把实时股价和对应的持仓行做绑定,所以不管循环渲染多少行,读的都是同一个最后被覆盖的股价值 - 附带存在两个小bug:
render_template传参时price=price和total_value=total_value之间漏了逗号;总市值累加写在循环外部,只会累计最后一只股票的价值,算不对总额 - 之前尝试调整Jinja取值写法、改portfolio结构没解决的核心是:传递给模板的数据源本身没有逐行绑定对应股价,单条全局字典没有办法存多只股票的独立数据,不管模板怎么取值都拿不到逐行的正确值
修复后的后端逻辑
把原来存单条数据的字典,改成存独立字典的列表,每只股票的名称、代码、股数、实时价、总市值都作为独立项追加到列表里,循环内直接累计总市值:
@app.route("/") @login_required def index(): """Show portfolio of stocks""" # 拉取用户持仓聚合数据 rows = db.execute( "SELECT name, symbol, SUM(shares) AS shares FROM purchases WHERE users_id = ? GROUP BY name, symbol", session["user_id"] ) # 拉取用户现金余额 user_info = db.execute("SELECT * FROM users WHERE id = ?", session["user_id"]) cash = user_info[0]["cash"] if not rows or not cash: return render_template("empty_portfolio.html") portfolio_list = [] sum_total_value = 0 for row in rows: symbol = row["symbol"] shares = row["shares"] # 拉取当前股票实时价 stock = lookup(symbol) price = stock["price"] total_value = shares * price # 把当前股票的完整信息作为独立字典追加到列表 portfolio_list.append({ "name": row["name"], "symbol": symbol, "shares": shares, "price": price, "total_value": total_value }) # 循环内累计总市值 sum_total_value += total_value grand_total = cash + sum_total_value return render_template( "index.html", portfolio_list=portfolio_list, cash=cash, grand_total=grand_total )
修复后的前端模板逻辑
把原来遍历无股价字段的数据库结果集rows,改成遍历绑定了逐行股价的portfolio_list,每一行读取当前循环项的独立字段:
<table> <thead> <tr> <th>Stock</th> <th>Symbol</th> <th>Shares</th> <th>Price</th> <th>Total Value</th> </tr> </thead> <tbody> {% for stock in portfolio_list %} <tr> <td>{{ stock.name }}</td> <td>{{ stock.symbol.upper() }}</td> <td>{{ stock.shares }}</td> <td>{{ stock.price | usd }}</td> <td>{{ stock.total_value | usd }}</td> </tr> {% endfor %} <tr> <td colspan="4">Cash Balance</td> <td>{{ cash | usd }}</td> </tr> <tr> <td colspan="4">GRAND TOTAL</td> <td>{{ grand_total | usd }}</td> </tr> </tbody> </table>
修复后逐行渲染的股价、总市值都会对应到当前行的股票,不会被最后一行的结果覆盖,总金额计算也会完整累计所有持仓的价值。
内容的提问来源于stack exchange,提问作者marg
相关产品推荐
相关产品推荐

