Table of contents
1.
Introduction
2.
Features of Form in Web2py
3.
Process and Validate Methods  
4.
Conditional Fields 
5.
Hidden Fields 
6.
Keepvalues 
7.
Dbio
8.
Hideerror
9.
Onvalidation 
10.
Detect record change 
11.
Forms and Redirection 
12.
Multiple Forms Per page 
13.
Sharing forms
14.
Adding a button to forms 
15.
Frequently Asked Questions
15.1.
Is web2py worth learning?
15.2.
What is the use of web2py?
15.3.
Is web2py an MVC model?
15.4.
Does web2py support Python 3?
15.5.
Which is better, web2py or Flask?
16.
Conclusion 
Last Updated: Mar 27, 2024

Some of the forms feature in web2py

Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

Web2Py is written in Python and programmable in Python. A free, open-source web framework named Web2py allows for quickly creating safe, database-driven online applications. Web2py is a full-stack framework that includes all the components needed to build fully functional online applications.

Introduction

Web2py is the ideal framework for a Python programmer who wants to build a website utilizing a quick, open-source, full-stack framework. Web2py assists us in creating database-driven web applications that are quick, scalable, and portable. 

Before discussing the form features in web2py, let's discuss the form. 

form is a document section containing controls such as text fields, password fields, checkboxes, radio buttons, submit buttons, menus, etc.

A form facilitates the user to enter data that will be sent to the server for processing, such as name, email address, password, phone number, etc. 

You can learn more about forms here.

Features of Form in Web2py

Let us start discussing the features of form in web2py: 

all web2py form features

Let us see each one this one by one: 

Process and Validate Methods  

Process and Validate Methods 

A shortcut for 

form.accepts(request.post_vars, session, ...)

Is 

form.process(...).accepted

The request and session parameters are not required for the latter (although you can specify them optionally). It differs from accepted further in that it gives the form back. Process calls accept and transmit their arguments to one another internally. Accepts returns a value that is saved in form.  

The process function accepts an additional parameter that it does not take, but it does take:

  • message_onsuccess
  • If the value is equal to "flash" (the default) and the form is submitted, the message_onsuccess will flash.

     
  • message_onfailure
  • When the form's validation fails and the value is equal to "flash" (the default), the message described above will be flashed.

 

  • Next specify where to send the user after submitting the form.

Functions like lambda form: do_something can be used for onsuccess and onfailure (form).

form.validate(...)

It is a shortcut for 

form.process(..., dbio=False).accepted

Conditional Fields 

Conditional Fields

There are situations when you want a field to only appear under those circumstances. Think of the following model, for instance:  

db.define_table('purchase', Field('have_coupon', 'boolean'), Field('coupon_code'))

If and only if the coupon field is checked, you want to display the field coupon_code. JavaScript allows for this. You can benefit from web2py by having it create that JavaScript for you. Using the field show if attribute, you only need to define that the field is conditional on an expression. 

def index():
    db.purchase.coupon_code.show_if = (db.purchase.have_coupon==True)
    form = SQLFORM(db.purchase).process()
    return dict(form = form)

The DAL syntax you use for database queries is used in the query value of show_if. The distinction is that this query is run when the user modifies the form in the browser rather than the database because it was translated to JavaScript and delivered there. 

Hidden Fields 

Hidden Fields

Due to the prior call to the accepts function, and once the aforementioned form object is serialized by {{=form}}, it now appears as follows:
 

<form enctype="multipart/form-data" action="" method="post">
your name:
<input name="NAME" />
<input type="SUBMIT" />
<input value="12546632145" type="hidden" name="_key" />
<input value="default" type="hidden" name="_name" />
</form>


"_key" and "_name," two hidden fields, are present. They play two distinct but crucial functions brought about by the call to accept:
 

  • Web2py uses the secret field "_formkey" as a one-time token to avoid double submission of forms. When the form is serialized and stored in the session, the value of this key is created. This value must match when the form is submitted or otherwise, the acceptor returns False without raising any issues, acting as though the form had never been submitted. This is due to web2py's inability to ascertain whether the form was correctly submitted.
     
  • Web2py generates the name of the form in the hidden field "_formname," although the name can be changed. This field is required to enable pages that contain and handle numerous forms. Web2py uses the names of the various submitted forms to distinguish them.
     
  • FORM(..., hidden=dict(...)) specifies optional hidden fields.
     

The form above fails validation if the "name" field is left empty when it is submitted. When the form is serialized once more, the following appears:
 

<form enctype="multipart/form-data" action="" method="post">
your name:
<input value="" name="NAME" />
<div class="error">cannot be empty!</div>
<input type="SUBMIT" />
<input value="12546632145" type="hidden" name="_key" />
<input value="default" type="hidden" name="_name" />
</form>


Be aware that the serialized form contains a DIV with the class "error". To inform the user that a field did not pass validation, web2py includes this error message in the form. When a form is submitted, the accepts method recognizes that it has been submitted, checks to see if the field "name" is empty or needed, and then inserts the error message from the validator into the form. 

Keepvalues 

Keepvalues

When a form is submitted, and there is no redirection, the same form is displayed again. The optional argument keepvalues instructs web2py what to do. The form is cleared by default. The form is pre-populated using the previously entered values if keepvalues is set to True. This is helpful when you have a form meant to be used frequently to insert numerous similar records.

Dbio

After accepting a form, web2py will not insert or update any databases if the dbio parameter is set to False. 

Hideerror

If hideerror is set to True and there are errors in the form, they won't be displayed when rendered (it will be up to you to display them from form.errors somehow).

Onvalidation 

Onvalidation

The onvalidation argument has two possible values: None and a function that accepts a form but returns null. If the validation is successful, the form would be sent to this method, which would be called right away before anything else. This function serves various functions, such as performing further checks on the form and ultimately adding errors, computing the values of some fields based on the values of other fields, or starting an action (such as sending an email) prior to creating or updating a record. 

Here is an example: 

db.define_table('numbers',
    Field('first', 'integer'),
    Field('second', 'integer'),
    Field('third', 'integer', readable=False, writable=False))

def my_form_processing(form):
    third = form.vars.first * form.vars.second
    if third < 0:
      form.errors.second = 'first*second cannot be negative'
    else:
      form.vars.third = third

def insert_numbers():
  form = SQLFORM(db.numbers)
  if form.process(onvalidation=my_form_processing).accepted:
      session.flash = 'record inserted'
      redirect(URL())
  return dict(form=form)

Detect record change 

Detect record change

There is a slight chance that another user may be editing the same record while you are filling out a form to edit it. Therefore, we want to look for potential conflicts before saving the record. This is possible:db.define_table('dog', Field('name')) 

def edit_dog():
    dog = db.dog(request.args(0)) or redirect(URL('error'))
    form=SQLFORM(db.dog, dog)
    form.process(detect_record_change=True)
    if form.record_changed:
        # do something
    elif form.accepted:
        # do something else
    else:
        # do nothing
    return dict(form=form)

record_changed works only with an SQLFORM and not with a FORM.

Forms and Redirection 

Forms and Redirection

Forms are most frequently used with self-submission, which causes the action that created the form to process the submitted field variables. It is rare to show the current page once the form has been submitted and accepted (something we are doing here only to keep things simple). The visitor is often forwarded to a "next" page.  

Here is an example:

def display_form():
    form = FORM('Your name:',
              INPUT(_name='name', requires=IS_NOT_EMPTY()),
              INPUT(_type='submit'))
    if form.process().accepted:
        session.flash = 'form accepted'
        redirect(URL('next'))
    elif form.errors:
        response.flash = 'form has errors'
    else:
        response.flash = 'please fill the form'
    return dict(form=form)

def next():
    return dict()

Use session.flash rather than a response to set a flash on the subsequent page as opposed to the one that is now being displayed. flash. After redirection, web2py transfers the former into the latter. Keep in mind that you must avoid sessions when using session.flash. forget(). 

Multiple Forms Per page 

Multiple Forms Per page

The information in this section covers both FORM and SQLFORM objects. Multiple forms can be displayed on a same page, but you must give web2py the ability to distinguish between them. Web2py automatically gives them various names if SQLFORM derives them from different tables; otherwise, you must explicitly give them alternative form names. 

Here's an illustration: 

def two_forms():
    form1 = FORM(INPUT(_name='name', requires=IS_NOT_EMPTY()),
                INPUT(_type='submit'), _name='form_one')
    form2 = FORM(INPUT(_name='name', requires=IS_NOT_EMPTY()),
                INPUT(_type='submit'), _name='form_two')
    if form1.process(formname='form_one').accepted:
        response.flash = 'form one accepted'
    if form2.process(formname='form_two').accepted:
        response.flash = 'form two accepted'
    return dict(form1=form1, form2=form2)

Sharing forms

Sharing forms

The information in this section covers both FORM and SQLFORM objects. Although what we outline here is feasible, having forms users may self-submit is always a wise choice. The action that delivers the form and the action that receives it may occasionally belong to different applications, leaving you with no other option. 

A form that submits to a different action can be created. This is accomplished by including the URL of the processing action in the FORM or SQLFORM object's attributes. 

For instance: 

 

form = FORM(INPUT(_name='name', requires=IS_NOT_EMPTY()),
        INPUT(_type='submit'), _action=URL('page_two'))

def page_one():
    return dict(form=form)

def page_two():
    if form.process(session=None, formname=None).accepted:
        response.flash = 'form accepted'
    else:
        response.flash = 'there was an error in the form'
    return dict()

 

In order to avoid repeating ourselves, we have defined "page_one" and "page_two" only once by placing them outside of all the actions. This is because they both use the same form. Every time before relinquishing control to the called action, the common section of code at the beginning of a controller is executed. 

The form has no name and no key because "page one" neither calls the process nor accepts it. Thus you must pass session=None and set formname=None in the process if you want the form to be valid when "page two" receives it. 

Adding a button to forms 

Adding a button to forms

A form typically has just one submit button. It's typical to wish to include a "back" button that sends the user to another page rather than submitting the form.

The add button method can be used to accomplish this:

form.add_button('Back', URL('other_page'))

More than one button can be added to a form. The value of the button (its text) and the URL to which to redirect are the inputs to add the button.

Frequently Asked Questions

Is web2py worth learning?

Web2py is a top-notch framework, yes. The simplicity of usage, from installation to learning to code to distribution to deployment, is a key objective of web2py.

What is the use of web2py?

Python dynamic web content programming is made possible via Web2py. Web2py is made to make laborious web development jobs more manageable, such as creating web forms from scratch, while a web developer can still do it if necessary.

Is web2py an MVC model?

The Ruby on Rails and Django frameworks inspired the creation of web2py. Web2py is similar to these frameworks in that it emphasizes rapid development, prefers convention over configuration, and adheres to the model-view-controller (MVC) architectural pattern.

Does web2py support Python 3?

Web2py functions on Python 2.7 and Python 3 along with CPython (the C implementation) and PyPy (Python written in Python).

Which is better, web2py or Flask?

The majority of the Slant community suggests Flask when comparing web2py to that framework. What are the best backend web frameworks, as in the question? Web2py is ranked 19th, while Flask is placed fourth. 

Conclusion 

This article has an extensive understanding of the forms in web2py and all the features available. 

After reading about  Other types of Forms in web2py, refer to the web2py web framework,

What is the web2py web frameworkweb2py introductionweb2py installationCreating a New Web2Py ApplicationWeb2Py - Prepare the ToolWeb2Py - Troubleshooting Use Cases, and Web2Py - Capacity Planning Use CasesApplication development using PythonIntroduction to Python- Coding Ninjas for a deeper understanding of web2py development and other related topics. 

Refer to our Guided Path on Coding Ninjas Studio to upskill yourself in Data Structures and AlgorithmsCompetitive ProgrammingJavaScriptSystem Design, and many more! 

Thank you

Live masterclass