简体   繁体   English

在Peewee中使用optgroup生成select

[英]Generate select with optgroup in Peewee

I have the following models in a flask application with the Peewee ORM: 我在带有Peewee ORM的烧瓶应用程序中具有以下模型:

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

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

I want to generate a multiple select field, in which each course is an optgroup and each activity is an option in that opgroup with Jinja. 我想生成一个多重选择字段,其中每个课程都是一个optgroup,每个活动都是Jinja在该opgroup中的一个选项。

Say I have something like this: 说我有这样的事情:

  • Course I 课程一
    • Activity I 活动一
    • Activity II 活动二
    • Activity III 活动三
  • Course II 课程二
    • Activity IV 活动四
    • Activity V 活动五

that is, the ForeignKeyField in Activity I, II and III points to Course I, while the ForeignKeyField in Course II points to Activity IV and V. 也就是说,活动I,II和III中的ForeignKeyField指向课程I,而课程II中的ForeignKeyField指向活动IV和V。

I have the following view in my Flask application: 我的Flask应用程序中具有以下视图:

@app.route("/activities")
@login_required
def activities():
    activities = Activity.select()
    return render_template("activities.html", 
    activities = activities)

I want to get something like this: 我想得到这样的东西:

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

It is easy to get this without optgroup part in Jinja: 在Jinja中没有optgroup的部分很容易得到这个:

<select>
{% for activity in activities %} 
<option value="{{activity.id}}">{{activity.name}}</option>
{% endfor %}
</select>

but I have no idea how to get the Course.name field in the optgroup and then the activities that have their ForeignKeyField point to this course in the options within this optgroup. 但是我不知道如何在optgroup中获取Course.name字段,然后使具有ForeignKeyField的活动在此optgroup中的选项中指向该课程。 The only solution I can come up with is to run through all courses in a for loop and then have another for loop within that for loop to run through all activities and generate a new option if the activity.Course.name field matches course.name, but this is horribly inefficient, since you have to loop through all activities for each course. 我能想到的唯一解决方案是在一个for循环中遍历所有课程,然后在该for循环中包含另一个for循环以遍历所有活动,如果activity.Course.name字段与course.name匹配,则生成一个新选项,但效率极低,因为您必须遍历每门课程的所有活动。

Is there an easy and efficient way to generate this select box? 是否有一种简单有效的方法来生成此选择框?

You will want to have a look at the docs for more information, but Pewee supports joins out of the box: 您将需要查看文档以获取更多信息,但是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

Then, in your Jinja template you can simply: 然后,在您的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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM