Flask Wolf Book Notes | 04_Form

Please add a picture description

4 forms

Forms are one of the most common ways to interact with users. The Python packages covered in this chapter include WTForms , Flask-WTF , and Flask-CKEditor . (p104)

4.1 HTML form

Forms are created by <form>tags, and <input>fields are created by tags.

<form method="post">
    <input type="text" name="username" placeholder="用户名">
</form>

WTForms : Supports the use of class definition forms in Python, and then generates corresponding HTML codes through class definitions.

4.2 Using Flask-WTF

Flask-WTF integrates form data analysis, CSRF protection, file upload and other functions in Flask.

# 设置密钥,flask-wtf使用程序密钥来对csrf令牌进行签名(?)
app.secret_key = 'secret string'

Define the form class :

from wtforms import From

class LoginForm(Form):
    ...
  • Commonly used WTForms fields, common parameters of instantiated fields, and commonly used WTForms validators, see (p107).

Output HTML code :

>>> form = LoginForm()
>>> form.username()  # 假设在类中定义了username字段
>>> form.username.label()
  • Add additional attributes : the output field HTML code only contains idand nameattributes by default, and other attributes can be:
    • 1. Use the render_kw attribute (p109)
    • 2. Pass in when calling

Render the form in the template : We need to pass the form class instance into the template, and then call the properties of the form class in the template to get the HTML code corresponding to the field.

return render_template('basic.html', form=form)
<form method="post">
    {
   
   { form.csrf_token }}
    {
   
   { form.username.label }}
    {
   
   { form.username(class='form-contorl') }} <!-- 调用时传入额外属性值 -->
</form>
  • CSRF field : This field will be automatically verified after the form is submitted, and it needs to be rendered in order to pass the verification.

  • You can manually write the code of the HTML form, and the name attribute is consistent with the form class.

4.3 Processing form data

1 Process : Parse request --> convert to Python data type --> verify --> process.

2 Submit the form : In HTML, when <form>the submit field of type submit in the form declared by the tag is clicked, an HTTP request to submit the form will be created.

Attributes that control submission behavior in HTML forms : action (target URL), method (HTTP request method), enctype (form data encoding type). (p112)

3 Validate the form data :

  • Client verification : It can dynamically prompt the user in real time whether the input is correct, reducing the server load. Can be implemented through HTML5 built-in validation attributes, or Javascript.
  • Server-side validation : Required because the client side is unreliable.
<!-- 使用html5属性 -->
<input type="text" name=username" required>
  • WTForms verification mechanism : Pass in data when instantiating the form class, and then call validate()the method of the instance, and the error message will be stored in errorsthe dictionary corresponding to the attribute of the instance.
>>> form.errors # 错误消息字典
  • Get data : The data attribute is a dictionary that matches all fields and corresponding data.
>>> form.username.data
  • PRG mode : (Post/Redirect/Get), in the browser, the default behavior when refreshing the page is to send the previous request, which will lead to repeated submission of the form. So a redirect response (GET) should be returned after processing the form.

4 Render error messages : WTForms will add error messages to the form class errorsproperties, which is a dictionary that matches the class properties as form fields to the corresponding list of error messages .

>>> form.username.errors

4.4 Form advanced practice

Tips for simplifying the process of working with forms, and some unconventional uses of forms .

1 Set the error message language : as follows, all inherited MyBaseFormform classes will use the newly set default language for error messages.

from flask_wtf import FlaskForm 

app = Flask(__name__)
app.config['WTF_I18N_ENABLED'] = False

class MyBaseForm(FlaskForm):
    class Meta:
        locals = ['zh']
    
class HelloFrom(MyBaseForm):
    ...

Doubt : What is the operation of defining a Meta class inside the class?

2 Rendering forms with macros : When rendering forms in templates, there is a lot of repetitive work: get <input>definition, get <label>definition, render error messages. To avoid repeating this code for each field , a macro can be created. (p120)

{% macro form_field(field) %}
	{
   
   { field.label}}<br>
	{
   
   { field(**kwargs) }}<br>
	{% if field.errors %}
		{% for error in field.errors %}
			{
   
   { error }}
		{% endfor %}
	{% endif %}
{% end macro %}

3 Custom validator : A validator refers to a callable object that is passed in the validators parameter list when defining a field , and accepts formand field(field) two positional parameters. (p121)

  • Inline validator : Defined in the form class to validate a specific field.
  • Global validators : reusable. Define a function that throws an exception when validation fails ValidateionError. If you need to support parameters, you can use the factory function form .

Factory function : A function that returns a callable object.

4 File upload :

  • Rendering fields : In HTML, rendering a file upload field only needs to set the attribute value <inputof the field typeto file.
<input type="file">

You can use the classes provided by Flask-WTF FileFieldto create a file upload field, and the validators include FileRequired(whether it contains a file object) and FileAllowed(validate the file type). In addition, the file size can be limited by limiting the maximum length of the request message:

app.config['MAX_CONTENT_LENGTH'] = 3 * 1024 * 1024
  • Obtaining files : It can be obtained in request.files and parsed into a FileStorage object in Werkzeug . But Flask-WTF will automatically get
request.files.get('photo')

# 在Flask-WTF中
f = form.photo.data
  • Handle file names : You can filter dangerous characters in file names, or rename them uniformly (using uuid).
  • Others : There are also issues such as saving files , obtaining saved files , uploading multiple files, etc., which are omitted here, and you can take a closer look when you use them!

Doubt : the file was renamed using uuid , how to find this file later, and save the file name to the database? (after all the filenames are randomly generated)

Multiple files : Click a button to select and upload multiple files at one time.


Experience notes : I feel that the file upload has a lot of twists and turns, and I was a little confused for a while.

5 Using Flask-CKEditor to integrate a rich text editor : it feels like a black box to me (p129)

Doubt : In what form should the text be saved?

6 Multiple submit buttons for a single form :

For example, "publish article" and "save draft" need to be handled differently according to the button. Multiple types of fields can be created in the form class SubmitField, only clicked fields will appear in reqeust.formthe dictionary, and datawill be processed as Trueor when calling attributes False.

if form.validata_on_submit():
    if form.save.data:
        ...
    if form.publish.data:
        ...

7 Multiple forms on a single page :

The problem is to determine which form is currently being submitted.

  • Single View Handling : Set different names for the submit fields of the two forms.
  • Multi-view processing : Usually, two types of work are included in a view function that processes a form: rendering (GET) and processing the submitted form (POST). Therefore, you can create a rendering view function separately, and then create a submission view function for the two forms.

Note : The target URL of the form submission request actionis set through the property.

note

The content of this section of the form is relatively rich and complicated, and it involves many package switching operations. After reading it, there are still many details that are unclear. Occasionally, I realize that the "Python Craftsman" I read before helps me understand the content of this book.

When I was studying this section, I read more and did less. It was inevitable that I would forget the front after reading it. After reading a section of the book, I still can't understand it when I look at the relevant source code.

Guess you like

Origin blog.csdn.net/m0_63238256/article/details/132463648