web2py FORM - 按字符串字段而不是ID查找值

时间:2013-06-12 18:00:17

标签: python web2py web2py-modules

我在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时才提交表单(它有点像密码)。

这可能吗?

1 个答案:

答案 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

获得了验证类的模板