我在web2py中有这样的模型:
db.define_table('courses',
Field('course_name','string'))
db.define_table('auth_user',
....
....
Field('course_name',db.courses,label=T('Course Name'),
required=True,
requires=IS_IN_DB(db,db.courses.id,'%(course_name)s'),
如果我显示基于auth_user表的表单,则auth_user.course_name
字段由包含courses
表中所有课程的下拉菜单表示。正如所料,它使用courses.course_name
字段的内容而不是courses.ID
字段显示它们(因为IS_IN_DB要求中的字符串格式表示。
但是,我正在尝试对其进行修改,以便不使用下拉选择菜单,而只是显示文本字段。我希望用户能够输入课程名称,只要该名称是有效的course_name
,表单就能正常工作。
为此,我在widget=SQLFORM.widgets.string.widget
字段中添加了auth_user.course_name
属性。这正确显示文本框而不是下拉列表,但不允许用户输入course_name
。如果输入有效的courses.id
,它可以正常工作(如果它不是有效的ID,则显示预期的错误消息)。
但是,我无法弄清楚如何让它接受course_name
而不是ID。理论上我可以使用autocomplete插件(确实可以工作),但这样做的目的是允许用户只有在知道有效course_name
时才提交表单(它有点像密码)。
这可能吗?
答案 0 :(得分:2)
我通过使用自定义验证类(替换IS_IN_DB验证器)来解决这个问题。作为参考,这是我的验证器的样子:
class COURSE_NAME_VALIDATOR:
def __init__(self, error_message='Unknown course name. Please see your instructor.'):
self.e = error_message
def __call__(self, value):
if db(db.courses.course_name == value).select():
return (db(db.courses.course_name == value).select()[0].id, None)
return (value, self.e)
我从web2py手册(http://www.web2py.com/book/default/chapter/07#Custom-validators)
获得了验证类的模板