我在使用Peewee ORM的烧瓶应用程序中有以下模型:
class Course(db.Model):
name = CharField()
class Activity(db.Model):
course = ForeignKeyField(Course)
name = CharField()
我想生成一个多选字段,其中每个课程都是一个optgroup,每个活动都是该组与Jinja的选项。
说我有这样的事情:
即,活动I,II和III中的ForeignKeyField指向课程I,而课程II中的ForeignKeyField指向活动IV和V.
我在Flask应用程序中有以下视图:
@app.route("/activities")
@login_required
def activities():
activities = Activity.select()
return render_template("activities.html",
activities = activities)
我想得到这样的东西:
<select>
<optgroup label="Course I">
<option>Activity I</option>
<option>Activity II</option>
<option>Activity III</option>
</optgroup>
<optgroup label="Course II">
<option>Activity IV</option>
<option>Activity V</option>
</optgroup>
</select>
如果没有在Jinja的optgroup部分,很容易得到这个:
<select>
{% for activity in activities %}
<option value="{{activity.id}}">{{activity.name}}</option>
{% endfor %}
</select>
但我不知道如何在optgroup中获取Course.name字段,然后在此optgroup的选项中获取其ForeignKeyField指向此课程的活动。我能想到的唯一解决方案是在for循环中运行所有课程,然后在for循环中使用另一个for循环来运行所有活动,并在activity.Course.name字段匹配course.name时生成新选项,但这是非常低效的,因为你必须循环每个课程的所有活动。
是否有一种简单有效的方法来生成此选择框?
答案 0 :(得分:1)
您需要查看the docs以获取更多信息,但Pewee支持开箱即用的加入:
class Course(db.Model):
name = CharField()
class Activity(db.Model):
# Note that we have added a backreference
# to activities on the `Course` model with
# the `related_name` argument
# so we can do course.activites
course = ForeignKeyField(Course, related_name='activities')
name = CharField()
results = Course.select(Course, Activity).join(Activity)
# results is now a collection of courses, each course
# with all of its activities and it all should have been
# pulled out with one SQL query
然后,在您的Jinja模板中,您可以简单地:
<select name="activities">
{% for course in courses %}
<optgroup label="course.name">
{% for activity in course.activities %}
<option value="{{activity.id}}">{{activity.name}}</option>
{% endfor %}
</optgroup>
{% endfor %}
</select>