【发布时间】:2014-01-10 06:01:37
【问题描述】:
用例:使用表格为学生注册的每门课程输入成绩。
型号:
使用 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,
c.course_title,
FormField(StudentCourseForm)
)
form = GradesForm(request.POST, obj=student_courses)
return {'form': form}
如果可能,使用查询将是最简单的。根据SQLAlchemy docs,在会话上使用query() 方法会创建一个Query 对象。当像我在控制器中那样进行迭代时,这个对象是StudentCourse 对象的列表。
[<app.models.StudentCourse object at 0x10875bd50>, <app.models.StudentCourse object at 0x10875bed0>]
...我的进步到此结束。 任何帮助表示赞赏!
【问题讨论】:
-
class GradesForm(Form): pass然后以for course in courses: setattr(GradesForm, course.name, TextField(course.name, validators=[Required()]))为例:-) -
@SeanVieira:感谢您的意见。我读过那篇文章(以及演示该技术的section in the docs),但我不能以那种方式设置课程grades......至少不是那么容易。我可以使用这种技术来填充正确的 number 个字段,甚至可以使用 WTForms 验证,但我仍然需要在控制器中再次循环遍历课程以将表单数据分配给正确的对象在数据库中(而不是使用
form.populate_obj(user))。 -
我有一个没有分辨率的related issue。简而言之,如何将字符串变量传递给表单,以便可以使用数据预填充字段。一个示例用例:存储在多对多数据库中的以逗号分隔的标签列表。我认为正确的方法是运行查询将视图中的值传递给表单,但是我发现的每个示例都使用 populate_obj(post) 将整个 post 对象传递给表单。如果我需要在通过之前对帖子的属性之一做一些特殊的事情怎么办。
-
@bfin agghhh... 您能否请发布您的解决方案。最初的问题是几个月前发布的,所以我想你已经知道了。
标签: python sqlalchemy wtforms