A tutorial on Web Forms in the Python flask framework _python

Source: Internet
Author: User
Tags extend html form openid

Profile

In the previous chapters we defined a simple template for the homepage, and some of the modules that have not yet been implemented, such as users or posts, use mock objects as temporary placeholders.

In this chapter we'll see how to fill these blanks with Web forms.

Web Form is the most basic building element in Web application, we will implement user posting and application login function through form.

To complete this chapter you will need to make sure that the code is installed and working correctly based on the microblogging application code that is completed in the previous section.

Configuration

FLASK-WTF is the Flask framework extension for the Wtforms project, which we will use to help us process Web forms.

Most flask extensions need to define related configuration items, so let's start by creating a configuration file in the application root directory for use. Let's create this first (fileconfig.py):

csrf_enabled = True
secret_key = ' you-will-never-guess '

Quite simply, this is the 2 configuration items that FLASK-WTF needs to use. Csrf_enabled configuration enables cross-station request attack protection, which you need to turn on in most cases, which makes your application more secure.


The Secret_key setting is valid when CSRF is enabled, which generates an encrypted token for form validation, and you want to make sure that the key is complex enough not to be simply inferred.

The configuration file is now basically available. Project Creation Complete We can create the following files and edit (fileapp/__init__.py):

From flask import flask
 
app = Flask (__name__)
app.config.from_object (' config ') from the
 
app import views

User Login Form

A form created using FLASK-WTF is like an object and requires inheriting subclasses from the form class. You can then define some of the class's property variables as form fields in this subclass.

We want to create a login form that is used for user identification. But unlike the usual way of logging in to verify the username and password, we will use OPENID to process the login. The advantage of using OpenID is that we don't have to take care of the authentication process for the username and password and give it to OpenID to fix it, and it will return it to our user after the validated data. This is also more secure for users who use our site.


Using OpenID login requires only a single string, which is then sent to the OpenID server. In addition, we need to add a "Remember Me" box in the form, which is for people who don't want to be authenticated every time they come to our site. When this option is selected, the first time you log on, you will remember their login information with cookies in their browsers, and the next time you enter the site, you won't need to log in.

Let's start with our first form (fileapp/forms.py):

From FLASK.EXT.WTF import form, TextField, Booleanfield from
flask.ext.wtf import Required
 
class LoginForm (form ):
  OpenID = TextField (' OpenID ', validators = [Required ()])
  Remember_me = Booleanfield (' Remember_me ', default = False)

Appreciate this class, how concise, how clear. So simple, but very rich content. We introduced a Form class and then inherited the class, adding TextField and Booleanfield fields as required.

Also introduced is a form validation function Required, which can be appended to the field and used to check the data that the user fills out when the user submits the form. This Required function is used to prevent users from submitting empty data. There are a number of different forms validation functions in the FLASK-WTF, which we'll use later.


form template

Now our problem is that we need a template to display this login form. The good news is that the login form class We just created knows how to convert the fields to HTML, so we just need to focus on the page layout. Here is the template for our login form (fileapp/templates/login.html):

<!--extend from base layout-->
{% extends ' base.html '%}
 
{% block content%}
 
 

Let me be verbose, in this template, we once again use the way the template inherits. Use the extends statement to inherit the template content from the base.html. We'll continue to use this in the template we created later, so that we can keep all of our page layouts consistent.


This login template differs from the normal HTML form in that it uses the template parameter {{...}} to instantiate the form field, and the form field comes from the form class that we just defined, with the name form in the template parameter. When we use the view function to refer to the form class and render it to the template, we should pay special attention to the variable name that passes the form class to the template.

The CSRF (Cross-site forgery request) feature is turned on in the configuration, and the template parameter {{Form.hidden_tag ()}} is replaced with a hidden form field that prevents CSRF functionality. After the CSRF feature is turned on, this template parameter needs to be added to all templates ' forms.


The fields in the form object that we define can also be rendered by the template, and the related fields appear at the defined location simply by adding template parameters such as {{form.field_name}} to the appropriate location in the template. There are also some fields that can pass parameters, such as this OpenID field, we added a parameter to increase the width of its display to 80 characters.

Since we don't have a submit button defined in our form, we can only do it in plain form fields here. But a single button, in a form that has nothing to do with any data, does not necessarily define in a form class.

Form view

Witness the miracle of the moment the last step, we're going to write a view function that renders the login form object to the template.

This function is pretty simple and boring because we just have to pass the form object to the template. Here are the full contents of our view function (fileapp/views.py):

From flask import render_template, Flash, redirect out
app Import app from
forms import LoginForm
 
# Index Vie W function suppressed for brevity
 
@app. Route ('/login ', methods = [' Get ', ' POST '])
def login ():
  form = Loginfo RM () return
  render_template (' login.html ',
    title = ' Sign in ',
    form = form)

We introduce the login form class, then instantiate it into a variable, and then pass the variable to the template. This is what is necessary to render a form field.

The code above also introduces two new objects: Falsh and redirect, which you can use later.


Another thing to do is to add a new method to the routing adorner. Let flask understand that our view function supports get and POST requests. Otherwise, this view function responds only to get requests. We need to get the data that the user submits after filling out the form, which is passed from the POST request.

You can test the program in the browser to understand what is said above. According to the route associated with the view function, you should enter the Http://localhost:5000/login in the browser

Since we have not written any code to receive the data, it has not worked for you to submit the button at the midpoint of the page.

Receive data from a form

It is also worth mentioning that FLASK-WTF's handling of the form submission data makes our next task easier. Here is a new version of our login view function, which joins the form data validation and processing (fileapp/views.py):

@app. Route ('/login ', methods = [' Get ', ' POST '])
def login ():
  form = LoginForm ()
  if Form.validate_on_submit ():
    Flash (' Login requested for openid= "' + Form.openid.data + '", remember_me= ' + str (form.remember_me.data))
    Return redirect ('/index ') return
  render_template (' login.html ',
    title = ' Sign in ',
    form = form)

Validate_on_submit () This method does all the work of the form processing. It returns False If you call this method when you provide data to a one-way user (with a chestnut: The user modifies the submitted data before it). When this happens, you know. Don't understand? is to submit the data validation does not pass, you have to continue rendering the template.

When the form's Validate_on_submit () method is invoked when the request is submitted, it obtains all the submitted data from the request, and then validates the data using the validation function that is bound in the form field. Returns True if all data is validated through. This means you can safely use these form data.

It returns False as long as there is a field validation that does not pass. Then we need to return the data to the user and let them correct the error data. Next we will see how to display the error message to the user when the data validation fails.


When the Validate_on_submit () method returns True, our view function calls two new functions. They are all introduced from flask, and the flash function is used to display the defined message in the next open page. We use it to do debugging now. Because we do not have to do the user login module, so only need to put the user submitted to show the data on the line. Flash functions are useful, such as providing message feedback for some of the user's actions.

The message provided by the Flash function does not automatically appear on our site page, so we need to do something to make it appear on the page. In order for all of our pages to have this exciting feature, add it to the underlying template, following the updated base template (fileapp/templates/base.html):

 
 

Features in the template displaying flash messages I hope you understand.


Another new function that we use in the view function is redirect. This function notifies the user that the browser jumps to the specified address. In our view function, we use it to jump to the home page. Note that after the jump end of the page will also show the Flash function message Oh.

It's an exciting time to run our program and see how the form works. Instead of filling out the OpenID field in the form, see how Required this validation function works, blocking all requests to launch empty data from thousands of miles away.

Improve field validation

Our program is now in good condition, the submission of the required data will be blocked, but also return the form to allow users to modify, basically meet our requirements.

But there seems to be something less. If we give users a hint after the user submits the data, let them know what causes it, wouldn't it be wonderful! Luckily, it's easy to solve the problem with FLASK-WTF.

When form field validation fails, FLASK-WTF adds an error message to the form object. These messages are also available in the template, so we just need to add a little bit of stuff to the template to be OK.


This is the login template (fileapp/templates/login.html) on which we added validation messages:

<!--extend Base layout-->
{% extends "base.html"%}
 
{% block content%}
 
 

We only added a loop statement to the right of the OpenID field, which will display the message that the OpenID field validation failed. No matter how many fields your form has, error messages for all form field validation failures can be used in this way with form.errors. Field names. In this form, we are form.errors.openid. In order for the error message to be noticed by the user, we added a red CSS style to the message.

Process OpenID Login

In real life, we find that a lot of people don't know they have some public accounts. A number of big-name websites or service providers will provide their members with a public account certification. A chestnut, if you have a Google account, you actually have a public account, similar to Yahoo, AOL, Flickr and so on.

To make it easier for our users to use their public accounts simply, we will add links to these public accounts to a list so that users do not have to enter them manually.


We're going to define some of the public service providers that are available to the user into a list, and the list will be in the configuration file (fileconfig.py):

csrf_enabled = True
secret_key = ' you-will-never-guess '
 
openid_providers = [
  {' name ': ' Google ', ' url ': ' Https://www.google.com/accounts/o8/id '},
  {' name ': ' Yahoo ', ' url ': ' https://me.yahoo.com '},
  {' name ': ' AOL ', ' URL ': ' http://openid.aol.com/<username> '},
  {' name ': ' Flickr ', ' url ': ' http://www.flickr.com/< Username> '},
  {' name ': ' Myopenid ', ' url ': ' https://www.myopenid.com '}]

The next step is to use this list in our login view function:

@app. Route ('/login ', methods = [' Get ', ' POST '])
def login ():
  form = LoginForm ()
  if Form.validate_on_submit ():
    Flash (' Login requested for openid= "' + Form.openid.data + '", remember_me= ' + str (form.remember_me.data))
    Return redirect ('/index ') return
  render_template (' login.html ',
    title = ' Sign in ',
    form = form,
    providers = app.config[' Openid_providers '])

We introduced the configuration list of the public account service provider from the app.config, then introduced it as a parameter through the Render_template function to the template.


The next thing I want you to guess is that we need to display these service links in our login template.

<!--extend Base layout--> {% extends "base.html"%} {% block content%} <script type= "Text/javascript" > F
    Unction Set_openid (OpenID, pr) {u = openid.search (' <username> ') if (U!=-1) {/OpenID requires username user = prompt (' Enter your ' + PR + ' username: ') OpenID = openid.substr (0, u) + user} form = document.forms['
  Login ']; form.elements[' OpenID '].value = OpenID} </script>  

This time the template adds something that seems a little more. Some public accounts need to provide user name, in order to solve this we use a bit of JavaScript. When the user clicks on the relevant public account link, the user name of the public account will prompt the user to enter the user name, JavaScript will be processed into the user name available public account, and finally inserted into the OpenID field text box.

Here is the screenshot shown after clicking on the Google link in the login page:

Conclusion

We are currently making some progress on the user login form, but there is nothing you can do to log in to the site. At the moment we've been doing a little tinkering in the login interface because we haven't logged everything to the database yet.

So from the beginning of the next section, we'll get the whole database up and we'll actually complete our login system. Do not go away, please continue to pay attention.


Weibo (microblog) current version of the source code from the following address download:

Download Address: Microblog-0.3.zip

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.