在Peewee中使用optgroup生成选择

时间:2013-12-14 19:47:14

标签: python flask jinja2 peewee flask-peewee

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

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

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

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

说我有这样的事情:

  • 课程我
    • 活动I
    • 活动II
    • 活动III
  • 课程II
    • 活动IV
    • 活动五

即,活动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时生成新选项,但这是非常低效的,因为你必须循环每个课程的所有活动。

是否有一种简单有效的方法来生成此选择框?

1 个答案:

答案 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>