Domanda

I have a model like this in 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'),

If I display a form based on the auth_user table, the auth_user.course_name field is represented by a dropdown menu containing all of the courses in courses table. As expected, it displays them using the contents of the courses.course_name field, and not the courses.ID field (because of the string format representation in the IS_IN_DB requirement.

However, I'm trying to modify it such that instead of using a dropdown select menu, it just displays a text field. I'm expecting the user to be able to enter the name of a course, and the form will work properly as long as that name is a valid course_name.

To do that, I added a widget=SQLFORM.widgets.string.widget property to the auth_user.course_name field. That correctly displays a text box instead of the dropdown, but doesn't allow the user to enter a course_name. It works fine if a valid courses.id is entered (and displays the expected error message if it's not a valid ID).

However, I can't figure out how to make it accept a course_name instead of the ID. I could theoretically use the autocomplete plugin (which does indeed work), but the purpose of this is to allow the user to only submit the form if they know the valid course_name (it's kind of like a password).

Is this possible?

È stato utile?

Soluzione

I figured this out by using a custom validation class (replacing the IS_IN_DB validator). For reference, this is what my validator looks like:

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)

I got the template for the validation class from the web2py manual (http://www.web2py.com/book/default/chapter/07#Custom-validators)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top