Python - flask web forms

Python-flask web form

1. Protection CSRF

request.form can get the form data submitted by the POST request, and Flask-WTF expansion process can handle Web forms into a pleasant experience.

By default, Flask-WTF protect all forms against CSRF (Cross-Site Request Forgery, CSRF ) attacks. The malicious site would lead to a CSRF attack when the request is sent to another site by an attacker logged on.
To achieve CSRF protection, Flask-WTF settings requires a key. Flask-WTF using this encryption key generation token, then the token verification request form data authenticity. Key setting method shown in FIG.

app = Flask(__name__)
app.config['SECRET_KEY'] = 'hard to guess string'

app.config dictionary used to store the frame, and the program itself extended configuration variables. Use standard dictionary syntax will be able to add value to the app.config configuration object. This object also provides methods, configuration values ​​can be imported from a file or the environment.

SECRET_KEY configuration variables is a common key, and can be used in the Flask multiple third-party extensions. As the name, the encryption strength depending on the degree of confidentiality of the variable value. Different programs to use different keys **, but also to ensure that other people do not know the string you are using.

To enhance security, the key should not be written directly into the code, and you want to save the environment variable

2. Form class

When using Flask-WTF, each Web form is represented by a class that inherits from Form representation. This class defines a set of fields in a form, each field represented by objects. Subsidiary field object may be one or more validation function. Verification function is used to validate input values ​​submitted by the user to meet the requirements.

Defined form classes:

from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired

class NameForm(Form):
	name = StringField('What is your name?',validators=[Requird()])
	submit = SubmitField('Submit')

The fields in the form are defined as a class variable, the value of the variable is an object class corresponding field type. In this example, NameForm form has a text field called name and submit the name of a submit button. StringField class represents the attribute type = "text" element. SubmitField class represents the attribute type = "submit" element. The first constructor parameter field is used when the label form is rendered into HTML. Optional parameters validators StringField constructor a list specified by the verification function of the composition, before accepting the verification data in the data submitted by the user. Field validation function Required () ensure the submission is not empty

WTForms supported HTML standard fields as shown in Table:

Field Type Explanation
StringField Text fields
Text Area Field Multi-line text fields
PasswordField Password text field
HiddenField Hidden text field
DateField Text fields, the format is datetime.date
DateTimeField Text fields, the format is datetime.datetime
IntegerField Text fields, an integer value
DecimalField A text field, the value decimal.Decimal
FloatField A text field, as a float
BooleanField Check box, a value of True and False
RadioField A set of radio buttons SelectField drop-down list
SelectMultipleField Drop-down list, select a plurality of values
FileField File upload field
SubmitField Form submit button
FormField As fields are embedded in the form of another form
FieldList Field of a specific type.

3. In view of the function processing Form

View function index () must not only render the form, but also to receive data in a form

@app.route('/', methods=['GET', 'POST'])
def index():
    name = None
    form = NameForm()
    if form.validate_on_submit():
        name = form.name.data
        form.name.data = ''
    return render_template('index.html', form=form, name=name)

methods parameters app.route decorators tell Flask added in the URL mapping to this view function registered as a handler for GET and POST requests. If you do not specify the methods parameter, it is only the view function registered as a handler for GET requests.

POST joined the list of methods is necessary because the form is submitted will be treated as a POST request more convenient. Forms can also be submitted as a GET request, but no body GET request, the data submitted in the form of a query string appended to the URL, you can see in the address bar of your browser. Based on this and a plurality of other reasons, mostly as a POST request form is submitted for processing.

Effective local variable name used to store the name entered in the form, if not input, it is None. The code is shown above, it is used to create a class instance NameForm view showing a form function. After submitting the form, all data can be verified if the function accepts, so validate_on_submit () method returns a value of True, otherwise False. The return value of this function is the decision to re-render the form or processed form submission data.

Users access the program for the first time, the server will not receive a GET request form data, so validate_on_ submit () will return False. Content will be skipped if statement, by rendering the template processing request, and passes the object and the form of the name is None variable as a parameter. Users will see a form showing your browser.

After the user submits the form, the server receives a POST request contains data. validate_on_submit () will call on the name of the subsidiary field Required () validation function. If the name is not empty, it can be verified, validate_on_ submit () returns True. Now, the user enters the name of the properties available through the data field. In the if statement, the name assigned to the local variable name, then put the data property to an empty string, emptying form fields. The last line calls render_template () function template rendering, but this time the name of the parameter name is entered into the form, and therefore a welcome message will be displayed for the user.

4. The user session redirection and

There is a problem of availability of the latest version of hello.py. After entering the name of the user submits the form, and then click your browser's refresh button, you will see a warning inexplicable, asks for confirmation before submitting the form again. The reason why this happens is because the last request before resending the browser when you refresh the page has been sent off. If the request is a POST request containing form data, refresh the page to submit the form again. In most cases, this is not the ideal approach.

Many users do not understand the warnings sent by the browser. For this reason, it is best to let Web program as a last request POST request sent by the browser.

Implementation of this requirement is that, as a response to the POST request redirection instead of conventional response. Redirection is a special response is a response content URL, rather than a string containing the HTML code. When the browser receives this response, it will initiate a GET request to the redirected URL, displays the contents of the page. Load this page may spend a few microseconds, because we first have a second request to the server. In addition, users will not notice any difference. Now, the last request is a GET request, the refresh command can be used as normal as expected. This technique is called Post / Redirect / Get pattern.

However, this method will bring another problem. When the handles POST requests, using form.name.data get the name entered by the user, but once the end of the request, the data will be lost. Because the POST request using the redirect process, so the program needs to save the name entered, such a request after the redirect to obtain and use the name in order to build a real response.

The program may be stored in the user data session between the request "remember" the data. The user session is a private storage, is present in each connection to the server client. We introduced a user session in Chapter 2, which is a request context variable named session, like standard Python dictionaries as operations.

By default, the user's session cookie stored in the client, use the set SECRET_KEY cryptographically signed. If you tamper with the contents of the cookie, the signature will be invalid, the session will also fail.

from flask import Flask, render_template, session, redirect, url_for

@app.route('/', methods=['GET', 'POST'])
def index():
    form = NameForm()
    if form.validate_on_submit():
        session['name'] = form.name.data
        return redirect(url_for('index'))
    return render_template('index.html', form=form, name=session.get('name'))

In the previous version of the program, the name of a local variable is used to store user name entered in the form. This variable is now stored in the user session, namely session [ 'name'], so that between requests can remember the values ​​entered.

Now, the request contains a valid form data will eventually call the redirect () function. redirect () is an auxiliary function used to generate the HTTP redirect response. Parameter redirect () function is a redirection URL, URL redirection used herein is the root address of the program, thus redirect response could write simpler, write redirect ( '/'), but will be used to provide Flask the URL generating function url_for (). Recommended url_for () generates a URL, because the function uses URL mapping generated URL, URL and defined so as to ensure route compatible, and the revised routing name is still available.

url_for () first and only need to specify the parameters of the function is the name of the endpoint, that is, the internal name of the route. By default, the routing endpoint is the name of a corresponding view function. In this example, the processing function is a view of a root address index (), and therefore passed the url_for () function is the name index.
Finally, a change is located render_function () function, a session.get ( 'name') read directly from the session name parameter value. And ordinary dictionary, as used here get () Gets the dictionary corresponding to the key value to avoid anomalies key was not found, because for a nonexistent key, get () returns the default value None.

5.Flash news

After the completion of the request, and sometimes you need to let the user know the status has changed. Here you can use the confirmation message, warning or error reminder. A typical example is a user submitted a login form there is an error, the server sends back a response to re-render the login form, and displays a message in the form above, prompting the user to a user name or password is incorrect.

This function is a core feature of Flask, flash () function to achieve this effect.

from flask import Flask, render_template, session, redirect, url_for, flash

@app.route('/', methods=['GET', 'POST'])
def index():
    form = NameForm()
    if form.validate_on_submit():
        old_name = session.get('name')
        if old_name is not None and old_name != form.name.data:
            flash('Looks like you have changed your name!')
        session['name'] = form.name.data
        return redirect(url_for('index'))
    return render_template('index.html', form=form, name=session.get('name'))

In this example, the name of each submission will be stored and is compared in a user session name, and the name is stored in the session data from a previous submission in this form. If two names are not the same, it will call the flash () function displays a message in a response to the client's.
Calls only flash () function does not transform the message is displayed, the program uses templates to render these messages. The best news in the rendering of Flash-based template, all the pages because it can use these messages. Flask the get_flashed_ messages () function to open a template, to obtain and render the message

templates / base.html: rendering Flash news

{% block content %}
<div class="container">
    {% for message in get_flashed_messages() %}
    <div class="alert alert-warning">
        <button type="button" class="close" data-dismiss="alert">&times;</button>
        {{ message }}
    </div>
    {% endfor %}

    {% block page_content %}{% endblock %}
</div>
{% endblock %}

Using a loop in the template is because before each flash cycle request call () function generates a message, it may have a plurality of display messages queued. get_flashed_messages () function to get the message does not return again on the next call, so Flash message is displayed only once, then disappeared

Published 33 original articles · won praise 1 · views 2291

Guess you like

Origin blog.csdn.net/qq_40805620/article/details/100919489