If you benefit from web2py hope you feel encouraged to pay it forward by contributing back to society in whatever form you choose!

Adding a captcha to a form as shown in the book requires too much work!! ;-) Here is a simpler way to do it.

The idea is using a fake widget.



def captcha_field(request=request):
    from gluon.tools import Recaptcha
    w = lambda x,y: Recaptcha(request,
    return Field('captcha', 'string', label='verify', widget=w, default='ok')


    form = SQLFORM.factory(Field('name', requires=IS_NOT_EMPTY()),
                           Field('email', requires=[IS_NOT_EMPTY(), IS_EMAIL()]),
                           Field('content', 'text', requires=IS_NOT_EMPTY()),
    if form.process().accepted:


Related slices

Comments (2)

  • Login to post

  • 0
    jeremy-martin-11354 8 years ago

    Holy cow, so helpful. The only thing I can add is that if you're doing a register form with a password, doing the SQLFORM factory will not give you the "verify password" field by default. And if you update, you'll need to filter the form vars. So this is what I'm doing:


    form = SQLFORM.factory(db.auth_user
                           ,Field("verify_password", "password"
                                ,requires=IS_EXPR('value=={0}'.format(repr(request.vars.get('password', None)))
                                    ,error_message="Password fields don't match"))
                           ,Field("captcha", widget=captcha_callable, default="ok"))
    if form.process().accepted:

  • 0
    rochacbruno 11 years ago

    Nice slice!

    I would change a little to:

     def captcha_field(request=request, apikey, apisecret, fieldname="captcha", label="verify"):
        from gluon.tools import Recaptcha
        w = lambda x,y: Recaptcha(request,
        return Field(fieldname, 'string', label=label, widget=w, default='ok')


    And using with

    captcha_field(apikey, apisecret, "mycaptcha", "write the security code")

    Also I think it can be included as

    replies (1)
    • michelecomitini 11 years ago

      Those are nice, also it should be moved to a module by using current.request

Hosting graciously provided by:
Python Anywhere