如何使用WTForms填充对象列表?
使用案例:使用表格为学生注册的每门课程输入成绩.
模型: 使用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} 这会产生一个空白表单,所以我显然无法直接从Query对象填充表单中的数据.但是,即使在为每个课程创建一个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,FormField(StudentCourseForm) ) form = GradesForm(request.POST,obj=student_courses) return {'form': form} 如果可能,使用查询将是最简单的.根据SQLAlchemy docs,在会话上使用query()方法创建一个Query对象.像我在控制器中那样迭代时,此对象是StudentCourse对象的列表. [< app.models.StudentCourse对象位于0x10875bd50>,< app.models.StudentCourse对象位于0x10875bed0>] ……我的进步在这里结束了.任何帮助赞赏! 解决方法
我能够填充这些动态创建的表单的唯一方法是传递** kwargs,因此我将发布此方法作为答案,直到其他人可以找出基于对象的解决方案.
要填充表单: def view(request): ... data = {} for c in student_courses: data[c.course_title] = c.grade # Populate form form = GradesForm(request.POST,**data) ... 通过这种方式,我可以通过遍历字段在模板中呈现表单,并且在提交时,我将有一个dicts列表,然后我可以验证并使用它来更新我的数据库记录. 表单验证需要相同的方法: 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_obj()方法,那就太好了: def view(request): ... if request.method == 'POST' and form.validate(): form.populate_obj(student_courses) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |