0

我在带有 Peewee ORM 的烧瓶应用程序中有以下模型:

class Course(db.Model):
    name = CharField()

class Activity(db.Model):
    course = ForeignKeyField(Course)
    name = CharField()

我想生成一个多选字段,其中每门课程都是一个 optgroup,每个活动都是 Jinja 的 opgroup 中的一个选项。

说我有这样的事情:

  • 课程一
    • 活动一
    • 活动二
    • 活动三
  • 课程二
    • 活动四
    • 活动五

即Activity I、II和III中的ForeignKeyField指向Course I,而Course II中的ForeignKeyField指向Activity 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 匹配时生成一个新选项,但这是非常低效的,因为您必须遍历每门课程的所有活动。

有没有一种简单有效的方法来生成这个选择框?

4

1 回答 1

1

您需要查看文档以获取更多信息,但 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>
于 2013-12-15T02:31:42.333 回答