Python 如何使用WTForms填充对象列表?

Python 如何使用WTForms填充对象列表?,python,sqlalchemy,wtforms,Python,Sqlalchemy,Wtforms,用例:使用表单输入学生注册的每门课程的分数 型号: 使用SQLAlchemy,我定义了一个Student对象、一个Course对象和一个StudentCourse关联对象,该对象存储每个课程的每个学生的分数 class Student(Base): __tablename__ = 'students' id = Column(Integer, primary_key=True) name = Column(Text) courses = association_p

用例:使用表单输入学生注册的每门课程的分数

型号:

使用SQLAlchemy,我定义了一个
Student
对象、一个
Course
对象和一个
StudentCourse
关联对象,该对象存储每个课程的每个学生的分数

class Student(Base):
    __tablename__ = 'students'
    id = Column(Integer, primary_key=True)
    name = Column(Text)
    courses = association_proxy('student_courses', 'grade',
        creator=lambda k, v: StudentCourse(course_title=k, grade=v))
    ...

class Course(Base):
    __tablename__ = 'courses'
    id = Column(Integer, primary_key=True)
    title = Column(Text, unique=True)
    ...

# Link students to courses and store grades
class StudentCourse(Base):
    __tablename__ = 'student_courses'
    student_id = Column(Integer, ForeignKey(Student.id), primary_key=True)
    course_id = Column(Integer, ForeignKey(Course.id), primary_key=True)
    grade = Column(Integer)
    student = relationship(Student,backref=backref(
            'student_courses',
            collection_class=attribute_mapped_collection('course_title'),
            cascade='all, delete-orphan'))
    course = relationship(Course)

    @property
    def course_title(self):
        if self.course is not None:
            return self.course.title
        else:
            return self._course_title
    ...
查看:

我可以查询StudentCourses模型并构建相关表单,但我不知道如何将查询中的数据作为对象传递/检索

def view(request):
    student = Student.from_request(request)
    student_courses = DBSession.query(StudentCourse).\
        filter(StudentCourse.student_id == student.id).\
        all()

    class GradesForm(Form):
        pass

    # Add form field for each course the student is enrolled in
    for c in student_courses:
        setattr(GradesForm,
                c.course_title,
                IntegerField()
                )

    form = GradesForm(request.POST, obj=student_courses) # this doesn't populate the form

    return {'form': form}
这将生成一个空白表单,因此我显然无法直接使用
查询
对象中的数据填充表单。但是我没有成功地用任何类型的对象填充表单,即使是在为每个课程创建带有
FormField
类型的表单时:

class StudentCourseForm(Form):
    course_title = StringField()
    grade = IntegerField()

def view(request):
    ...
    class GradesForm(Form):
        pass

    # Add form field for each course
    for c in student_courses:
        setattr(GradesForm,
                c.course_title,
                FormField(StudentCourseForm)
                )

    form = GradesForm(request.POST, obj=student_courses)

    return {'form': form}
如果可能的话,使用查询将是最简单的。根据,在会话上使用
query()
方法创建
query
对象。当像我在控制器中那样迭代时,这个对象是
StudentCourse
对象的列表

[,]


…我的进步到此为止感谢您的帮助

我能够填充这些动态创建的表单的唯一方法是通过传递**kwargs,因此我将发布此方法作为答案,直到其他人能够找到基于对象的解决方案

要填充表单,请执行以下操作:

def view(request):
    ...
    data = {}
    for c in student_courses:
        data[c.course_title] = c.grade

    # Populate form
    form = GradesForm(request.POST, **data)
    ...
通过这种方式,我可以通过迭代字段在模板中呈现表单,提交时,我将有一个dict列表,然后我可以验证并使用它更新数据库记录

表单验证需要相同的方法:

def view(request):
    ...
    # Validate and persist form data
    if request.method == 'POST' and form.validate():
        for c in student_courses:
            student.courses[c.title] = form[c.title].data
这是可行的,但如果我能使用WTForms
populate\u obj()
方法那就太好了:

def view(request):
    ...
    if request.method == 'POST' and form.validate():
        form.populate_obj(student_courses)

课程中课程的
等级表单(表单)可能重复:pass
然后
:setattr(等级表单,课程名称,文本字段(课程名称,验证器=[Required()])
例如:-)@SeanVieira:感谢您的输入。我读过那篇文章(以及演示这项技术的文章),但我不能那样设置课程分数……至少不那么容易。我可以使用此技术填充正确数量的字段,甚至可以使用WTForms验证,但我仍然必须在控制器中再次循环课程,以将表单数据分配给数据库中的正确对象(而不是使用
表单。填充对象(用户)
)。我有一个没有解析的问题。简言之,如何将字符串变量传递给表单,以便可以使用数据预发布字段。一个示例用例:存储在多对多数据库中的以逗号分隔的标记列表。我认为正确的方法是运行查询,将值从视图传递到表单,但我发现的每个示例都使用populate_obj(post),将整个post对象传递到表单。如果在通过之前我需要对post的某个属性做一些特殊的处理,该怎么办?@bfin agghh。。。你能把你的解决方案贴出来吗。最初的问题是几个月前发布的,所以我想你已经明白了。我不清楚我们的问题有多密切相关,但我认为我们的看法是错误的。populate_obj表示我们正在将数据传递给另一个对象。我们没有用另一个对象填充该对象,因此名为“填充对象…”。。。在我的例子中,我的PostForm映射到我的模型。这意味着该值已附加到该字段。无需指定值。该值已经存在。这是我的例子,它会有所帮助。@jwogrady:我的用例面临的挑战是,我没有对象可以传递给populate_obj方法,因为这个特定的表单是动态生成的。如果每个学生都注册在同一组课程中,那么我可以创建一个静态表单,将这些特定课程的成绩设置为用户类的属性,并传递该类的一个实例以进行数据填充/验证/持久化。不幸的是,这不是我的情况。。。