CS50姓名生成器:Jinja循环HTML输出格式化异常求助
问题:Jinja循环输出姓名时格式异常(带括号和字典结构)
我在使用Jinja for循环格式化姓名生成器的输出时遇到问题。代码里已经组合了名和姓,但输出到HTML时显示成带括号的字典结构,比如[{'name': 'Oswaldo'}, {'name': 'Navarro'}],不知道哪里需要修改。
我的代码
Python后端代码
from cs50 import SQL from flask import Flask, render_template, request import random # Configure application app = Flask(__name__) # Ensure templates are auto-reloaded app.config["TEMPLATES_AUTO_RELOAD"] = True # Configure CS50 Library to use SQLite database db = SQL("sqlite:///names.db") @app.route("/") def index(): return render_template("index.html") @app.route("/results", methods=["POST"]) def results(): gender = request.form.get("gender") number_results = int(request.form.get("number_results")) results = [] for i in range(number_results): if gender == "male": random_id_male = random.randint(1, 1000) random_id_last = random.randint(1, 1000) male_name = db.execute("SELECT name FROM male_names WHERE id = ?", random_id_male) last_name = db.execute("SELECT name FROM last_names WHERE id = ?", random_id_last) total_male = male_name + last_name results.append(total_male) elif gender == "female": random_id_female = random.randint(1, 1000) random_id_last = random.randint(1, 1000) female_name = db.execute("SELECT name FROM female_names WHERE id = ?", random_id_female) last_name = db.execute("SELECT name FROM last_names WHERE id = ?", random_id_last) total_female = female_name + last_name results.append(total_female) elif gender == "other": random_id_other = random.randint(1, 300) random_id_last = random.randint(1, 1000) other_name = db.execute("SELECT name FROM other_names WHERE id = ?", random_id_other) last_name = db.execute("SELECT name FROM last_names WHERE id = ?", random_id_last) total_other = other_name + last_name results.append(total_other) return render_template("index.html", results=results)
HTML模板(index.html)
<head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1, width=device-width"> <!-- Bootstrap 5.1 --> <link crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" rel="stylesheet"> <script crossorigin="anonymous" src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"></script> <link href="/static/styles.css" rel="stylesheet"> <title>Fantasy Name Generator</title> </head> <header> <!-- Background image --> <div class="p-5 text-center bg-image" style="background-image: url('https://images.pexels.com/photos/326055/pexels-photo-326055.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1'); height: 400px;"> <div class="mask" style="background-color: rgba(0, 0, 0, 0.6);"> <div class="d-flex justify-content-center align-items-center h-100"> <div class="text-white"> <h1 class="mb-3">Fantasy Name Generator</h1> </div> </div> </div> </div> <!-- Background image --> </header> <body> <!--Form to get data from user--> <form action="/results" method="post"> <!--radio buttons to choose gender--> <div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="gender" id="inlineRadio1" value="male"> <label class="form-check-label" for="inlineRadio1">Male</label> </div> <div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="gender" id="inlineRadio2" value="female"> <label class="form-check-label" for="inlineRadio2">Female</label> </div> <div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="gender" id="inlineRadio3" value="other"> <label class="form-check-label" for="inlineRadio3">Neutral</label> </div> <div class="flex flex-col items-center"> <label class="pb-1" for="number_results">results</label> <select name="number_results" id="number_results" required class="mb-4 rounded-md"> <option value="10" selected>10</option> <option value="20">20</option> <option value="30">30</option> <option value="40">40</option> <option value="50">50</option> </select> </div> <button class="btn btn-primary" type="submit">Generate Names</button> </form> <!-- Names get generated here --> <div id="results" class="transition flex flex-col pt-6 md:pt-8" > <ul aria-label="results" class="m-auto text-center font-medium tracking-wide column-count-1 sm:column-count-3 lg:column-count-5"> {% for result in results %} <ul class="">{{ result }}</ul> {% endfor %} </ul> </div> </body>
当前异常输出
[{'name': 'Oswaldo'}, {'name': 'Navarro'}] [{'name': 'Jamir'}, {'name': 'Wagner'}] [{'name': 'Rodrigo'}, {'name': 'Valenzuela'}] [{'name': 'Davion'}, {'name': 'Molina'}] [{'name': 'Zechariah'}, {'name': 'Austin'}] [{'name': 'Jace'}, {'name': 'Conner'}] [{'name': 'Valentino'}, {'name': 'Zavala'}] [{'name': 'Kadin'}, {'name': 'Leblanc'}] [{'name': 'Emmanuel'}, {'name': 'Mccann'}] [{'name': 'Alexander'}, {'name': 'Erickson'}]
问题原因
db.execute()执行SELECT查询后,返回的是包含单个字典的列表,比如查询男性名字会得到[{'name': 'Oswaldo'}]- 代码中直接将两个列表相加(如
male_name + last_name),得到包含两个字典的列表,传给模板后Jinja直接输出了列表和字典的原始字符串形式,导致格式异常。
解决方案
方案1:后端拼接好完整姓名(推荐)
在Python代码中提取字典里的name值,直接拼接成完整姓名字符串,再存入results列表:
修改每个性别分支的代码,以男性分支为例:
# 提取列表中第一个字典的name值 male_name = db.execute("SELECT name FROM male_names WHERE id = ?", random_id_male)[0]['name'] last_name = db.execute("SELECT name FROM last_names WHERE id = ?", random_id_last)[0]['name'] # 拼接成完整姓名 total_male = f"{male_name} {last_name}" results.append(total_male)
女性和中性分支做同样修改,最终results列表中存储的是"Oswaldo Navarro"这类字符串,模板中直接输出即可:
{% for result in results %} <li class="">{{ result }}</li> {% endfor %}
同时注意把模板里的<ul class="">{{ result }}</ul>改成<li>,因为外层已经有<ul>标签,嵌套<ul>会导致HTML结构错误。
方案2:模板中提取字典值
如果不想修改后端代码,可在Jinja模板中直接提取列表里的字典值:
{% for result in results %} <li class="">{{ result[0].name }} {{ result[1].name }}</li> {% endfor %}
这里result[0]是名的字典,result[1]是姓的字典,通过.name提取对应值并拼接。
内容的提问来源于stack exchange,提问作者ResistanceDown
相关产品推荐
相关产品推荐

