Flask-WTF extension, which is a wrapper WTForms and integrates perfectly with Flask applications. CSRF_ENABLED = True SECRET_KEY = 'you-will-never-guess' Flask-WTF extension needs. CSRF_ENABLED activates the prevention of fake cross-site requests. In most cases, you will want to enable this option, which will make your application more secure.SECRET_KEY needed only when CSRF enabled. It is used to create a cryptographic token that is used during form validation. When you write your application, make sure that your secret key is difficult to find. from flask import Flask app = Flask(__name__) app.config.from_object('config') from app import views Flask-WTF forms are represented as subclass objects of the Form class. The subclass of forms simply defines the form fields as variables in a class. from flask.ext.wtf import Form from wtforms import TextField, BooleanField from wtforms.validators import Required class LoginForm(Form): openid = TextField('openid', validators = [Required()]) remember_me = BooleanField('remember_me', default = False) Form class and two field classes that we need, TextField and BooleanField .Required is a validator, a function that can be attached to a field, to validate the data sent by the user. The Required validator simply checks that the field was not sent empty. Flask-WTF has a lot of validators, we will use some new ones in the future.LoginForm class that we just created knows how to render form fields in HTML, so we just need to concentrate on the layout. Here is our login template: (app / templates / login.html file): <!-- extend from base layout --> {% extends "base.html" %} {% block content %} <h1>Sign In</h1> <form action="" method="post" name="login"> {{form.hidden_tag()}} <p> Please enter your OpenID:<br> {{form.openid(size=80)}}<br> </p> <p>{{form.remember_me}} Remember Me</p> <p><input type="submit" value="Sign In"></p> </form> {% endblock %} base.html template through the inheritance operator, extending it. We will do this with all of our templates, ensuring that the layout is consistent across all pages.form template argument. We will take care of sending this template argument in the future when we write the view function that returns this template.form.hidden_tag() will be replaced with a hidden field to prevent CSRF, included in our settings file. This field must be in all of your forms if CSRF is enabled.{{form.field_name}} argument in the place of the template where the field is to be inserted. Some fields can take arguments. In our case, we ask the form to create our openid field with a width of 80 characters. from flask import render_template, flash, redirect from app import app from forms import LoginForm #   index    @app.route('/login', methods = ['GET', 'POST']) def login(): form = LoginForm() return render_template('login.html', title = 'Sign In', form = form) LoginForm class, created an instance of it and sent it to a template. This is all you need to draw the form fields.flash and redirect . We use them a little later.route decorator. Here we tell Flask that the view function accepts a GET and POST request. Without this, the view will only accept GET requests. We want to receive POST requests which will give the form with the data entered by the user.Flask-WTF facilitates our work is the processing of submitted data. This is a new version of our login view function, which validates and saves form data (app / views.py file): @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 method does all the processing. If you call the method when the form is submitted to the user (that is, before the user has the opportunity to enter data there), then he will return False , in which case you know that you must draw the template.validate_on_submit is called together as part of the form validate_on_submit request, it will collect all the data, run any validators attached to the fields, and if everything is OK, it returns True , which indicates the data is valid. This means that the data is safe to be included in the application.False and this will again cause the form to be drawn to the user, thereby making it possible to correct the errors. Later we will learn to show error messages when validation fails.validate_on_submit returns True , our view function calls two new functions imported from Flask. The Flash feature is a quick way to display a message on the next page presented to the user. In this case, we will use this for debugging as long as we do not have the infrastructure necessary for logging, instead, we will simply display a message that will show the sent data. Also, flash extremely useful on the production server to provide user feedback. <html> <head> {% if title %} <title>{{title}} - microblog</title> {% else %} <title>microblog</title> {% endif %} </head> <body> <div>Microblog: <a href="/index">Home</a></div> <hr> {% with messages = get_flashed_messages() %} {% if messages %} <ul> {% for message in messages %} <li>{{ message }} </li> {% endfor %} </ul> {% endif %} {% endwith %} {% block content %}{% endblock %} </body> </html> redirect . This function redirects the client web browser to another page, instead of the requested one. In our presentation function, we used a redirect to the main page developed in the previous sections. Keep in mind that flash messages will be displayed even if the function ends with redirection.Required validator stops the transfer process.Flask-WTF also facilitates this task.Flask-WTF adds a visual error message to the form object. These messages are available in the template, so we just need to add some logic to display them. <!-- extend base layout --> {% extends "base.html" %} {% block content %} <h1>Sign In</h1> <form action="" method="post" name="login"> {{form.hidden_tag()}} <p> Please enter your OpenID:<br> {{form.openid(size=80)}}<br> {% for error in form.errors.openid %} <span style="color: red;">[{{error}}]</span> {% endfor %}<br> </p> <p>{{form.remember_me}} Remember Me</p> <p><input type="submit" value="Sign In"></p> </form> {% endblock %} form.errors._ . In our case, we use form.errors.openid . We display these messages in red to draw the user's attention to them. 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' }]  @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']) app.config . Next, the list is added to the render_template call as a template argument. <!-- extend base layout --> {% extends "base.html" %} {% block content %} <script type="text/javascript"> function 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> <h1>Sign In</h1> <form action="" method="post" name="login"> {{form.hidden_tag()}} <p> Please enter your OpenID, or select one of the providers below:<br> {{form.openid(size=80)}} {% for error in form.errors.openid %} <span style="color: red;">[{{error}}]</span> {% endfor %}<br> |{% for pr in providers %} <a href="javascript:set_openid('{{pr.url}}', '{{pr.name}}');">{{pr.name}}</a> | {% endfor %} </p> <p>{{form.remember_me}} Remember Me</p> <p><input type="submit" value="Sign In"></p> </form> {% endblock %} 
Source: https://habr.com/ru/post/194062/
All Articles