Input from website users
In the Website Development Tutorial, you will often need to create forms to take input
from website users as known as the visitors. We are using the survey_form module for the
demo of input from website user. We will need to create new model to save the records
added by website visitors.
So, we can create the model and the corresponding fields in the survey.form model :
class SurveyForm(models.Model):
_name = 'survey.form'
name = fields.Char('Title', required=True)
email = fields.Char('Email', required=True)
phone = fields.Char('Phone', required=True)
dob = fields.Date('Release Date')
qualification = fields.Char('Qualification')
Add the views for the survey_form module as follows:
<record id="survey_form_tree" model="ir.ui.view">
<field name="name">survey.form.view.tree</field>
<field name="model">survey.form</field>
<field name="arch" type="xml">
<tree create="false">
<field name="name"/>
<field name="email"/>
<field name="phone"/>
<field name="dob"/>
<field name="qualification"/>
</tree>
</field>
</record>
Add access rights for the survey.module model in the ir.model.access.csv file, as
follows:
access_survey_form,survey_form.survey_form,model_survey_form,base.group_user,1,1,1,1
We have added a new model named Survey Form for the demo purpose, and now, we will add a
new template with HTML form for input the data from website.
Steps:-
To create a new route and template for the survey form page, follow these steps:
Step 1:
Create a new route in the controller file(main.py):
class SurveyFormController(http.Controller):
@http.route(['/survey_form'], type='http', auth="user", website=True)
def survey_form_view(self, **post):
name = post.get('name')
email = post.get('email')
phone = post.get('phone')
if name and email and phone:
request.env['survey.form'].sudo().create({
'name': name,
'email': email,
'phone': phone,
'dob': post.get('dob'),
'qualification': post.get('qualification')
})
return request.redirect('/survey_form?submitted=1')
return request.render('survey_form.survey_form_template',
{'submitted': post.get('submitted', False)})
We have created a route for submitting the survey form. The **post argument in the
function accepts all query parameters at the URL. You will also receive the form data
submitted in the **post argument. In the demo, we used the same controller to display
pages and submit surveys. If we find the data in **post, we create a new problem in the
survey.form model and then redirect the user to the survey page using the submitted
query parameters so that the user can see that the survey has been submitted. Submit
another survey if he or she wants.
We used sudo() to create a survey form record because a website visitor does not have the
access rights to create a new survey form record. This is when it is necessary to create
a survey form record if a user has submitted a survey from a web page. This is a
practical example of the use of sudo().
Step 2:
Create an HTML form in a template:
<template id="survey_form_template" name="Survey Form">
<t t-call="website.layout">
<div class="container s_website_form">
<h3>Survey Form</h3>
<t t-if="submitted">
<h3 class="alert alert-success mt16 mb16">
<i class="fa fa-thumbs-up"/>
Survey submitted successfully
</h3>
<a href="/survey_form">Submit another survey</a>
</t>
<t t-else="">
<div class="row">
<div class="col-6">
<form id="form_survey_form"
action="/survey_form" method="POST">
<input type="hidden" name="csrf_token"
t-att-value="request.csrf_token()"/>
<div class="s_website_form_rows row s_col_no_bgcolor">
<div class="form-group col-12">
<label for="name">Name</label>
<input type="text" class="form-control"
name="name" placeholder="Enter your name"
required="required"/>
</div>
<div class="form-group col-12">
<label for="email">Email</label>
<input type="email" class="form-control"
name="email" placeholder="Enter your mail-id"
required="required"/>
</div>
<div class="form-group col-12">
<label for="phone">Phone</label>
<input type="number" class="form-control"
name="phone" placeholder="Enter your name"
required="required"/>
</div>
<div class="form-group col-12">
<label for="dob">DOB</label>
<input type="date" class="form-control"
name="dob" placeholder="dd/mm/yyyy"/>
</div>
<div class="form-group col-12">
<label for="qualification">Qualification</label>
<select class="form-control" name="qualification">
<option value="">Select</option>
<option value="pg">Post Graduation</option>
<option value="ug">Graduation</option>
<option value="higher_secondary">Higher Secondary</option>
<option value="secondary">Secondary</option>
</select>
</div>
<div class="form-group col-12">
<input type="submit" class="btn btn-primary"
value="Submit"/>
</div>
</div>
</form>
</div>
</div>
</t>
</div>
</t>
</template>
We created a template for the Survey Form webpage, and when we submit a form we add a
conditional partition that shows the success message. We added <form> with five
fields. The website uses all the fields to get input from the user. However csrf_token
is used to prevent cross-site Request Forgery(CSRF) attacks. The user will not be able
to submit the form unless you use it in the form. When you submit the form, you will
receive the data submitted as the **post parameter in the survey_form_view().
Update the module and open the /survey_form URL. From this page, you can submit your
survey. After submitting, you can check them out in the corresponding survey_form tree
view in the backend.
In some cases, if you want to disable csrf validation, you can use
csrf=False in the route:
@http.route('/url', type='http',auth="user", website=True, csrf=False)
you can restrict the get requests by adding the method parameter in the
route like this:
@http.route('/url, type='http', method='POST' auth="user", website=True)