Search code examples
pythonweb2py

Invalid SQLFORM submit generates ticket instead of showing errors on form


Here is my db.py:

db.define_table('antenna_details',
                Field('antenna_name',required=True),
                Field('model_name',required=True),
                Field('project_name',required=True),
                Field('frequency_band',required=True),
                Field('polarization',required=True),
                Field('aperture_size',required=True),
                Field('fixer_availability',required=True),
                Field('weight',required=True),
                Field('material',required=True),
                Field('email_id',required=True,unique=True,requires=[IS_NOT_IN_DB]),
                Field('subject',type='text',required=True),
                Field('attached',type='upload', label="""
                    Antenna/feed Geometry
                    Electrical specification
                    Attach Simulated data in predicted form
                """)
)

db.antenna_details.email_id.requires=[IS_EMAIL(),IS_NOT_EMPTY()]
db.antenna_details.attached.requires=IS_NOT_EMPTY()
db.antenna_details.subject.rquires=IS_NOT_EMPTY()
db.antenna_details.material.requires=IS_NOT_EMPTY()
db.antenna_details.weight.requires=IS_NOT_EMPTY()
db.antenna_details.fixer_availability.requires=IS_NOT_EMPTY()
db.antenna_details.aperture_size.requires=IS_NOT_EMPTY()
db.antenna_details.polarization.requires=IS_NOT_EMPTY()
db.antenna_details.frequency_band.requires=IS_NOT_EMPTY()
db.antenna_details.project_name.requires=IS_NOT_EMPTY()
db.antenna_details.model_name.requires=IS_NOT_EMPTY()

And Here is my default.py index action:

def index():
    """
    example action using the internationalization operator T and flash
    rendered by views/default/index.html or views/generic.html

    if you need a simple wiki simply replace the two lines below with:
    return auth.wiki()
    """
    # response.flash = T("Hello World")
    # return dict(message=T('Welcome to web2py!'))

    form = SQLFORM(db.antenna_details).process()

    if form.process().accepted:
        response.flash = 'your data is posted'

    return dict(form=form)

Now when I hit http://127.0.0.1:8000/Test/default, I get the form and when I submit it with an email id that already exists in the database, I get a ticket that says this:

<class 'sqlite3.IntegrityError'> column email_id is not unique

There are other constraints as well in the model(specifically IS_NOT_EMPTY()) but when this constraint is violated, the app simply redirects user back to the form and shows error in red. But for the duplicate email, it throws a ticket.

Why is it happening and what needs to be done so that on violation of IS_NOT_IN_DB constraint on email, it should redirect back to the form and show error in red near the email field similar to what happens with violation of IS_NOT_EMPTY constraint?


Solution

  •                 Field('email_id',required=True,unique=True,requires=[IS_NOT_IN_DB]),
    ...
    db.antenna_details.email_id.requires=[IS_EMAIL(),IS_NOT_EMPTY()]
    

    There are two problems. First, your IS_NOT_IN_DB validator is incorrect -- it should be something like IS_NOT_IN_DB(db, 'antenna_details.email_id').

    Second, after you set the requires attribute of the email_id field to IS_NOT_IN_DB in the field definition, you then completely overwrite it with new validators, which do not include IS_NOT_IN_DB. You should either append the additional validators or define them all in once place. (For that matter, you can move all of your validator assignments into the field definitions rather than putting them all after the table definition.)