Python 如何使用WTForms填充对象列表?
用例:使用表单输入学生注册的每门课程的分数 型号: 使用SQLAlchemy,我定义了一个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
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
这是可行的,但如果我能使用WTFormspopulate\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方法,因为这个特定的表单是动态生成的。如果每个学生都注册在同一组课程中,那么我可以创建一个静态表单,将这些特定课程的成绩设置为用户类的属性,并传递该类的一个实例以进行数据填充/验证/持久化。不幸的是,这不是我的情况。。。