Flask10 登录模块表单框架表单渲染表单验证bookie请求之前钩子g对象编写装饰器

Posted 寻渝记

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flask10 登录模块表单框架表单渲染表单验证bookie请求之前钩子g对象编写装饰器相关的知识,希望对你有一定的参考价值。

from flask import Flask
from flask import request
from flask import render_template
from flask_wtf import CSRFProtect as WTF # 利用表单类去渲染模板时需要用到

from forms import LoginForm

app = Flask(__name__)
WTF(app) # 在app上注册一个 WTF (所有的flask插件都必须进行注册)
app.config.from_pyfile(\'config.py\') # 修改app的配置文件(使 WTF_CSRF_ENABLED 失效)


@app.route(\'/\')
def index():
    return render_template(\'index.html\')

@app.route(\'/login/\', methods=[\'GET\', \'POST\'])
def login():
    if request.method == \'GET\':
        print(\'GET请求\')
        liginForm = LoginForm() # 相当于java中利用无参构造器创建对象
        return render_template(\'login.html\', loginForm = liginForm)
    if request.method == \'POST\':
        print(\'POST请求\')
        loginForm = LoginForm(request.form)  # 相当于java中利用有参构造器创建对象
        print(loginForm)
        email = loginForm.email.data
        password = loginForm.password.data
        print("邮箱为:{},密码为:{}".format(email, password))
        if loginForm.validate():
            return render_template(\'index.html\')
        else:
            return \'表单验证失败,错误信息 -> \' + str(loginForm.errors)

print(app.url_map)


if __name__ == \'__main__\':
    app.run(debug=True)
python代码

 

 

1 一个请求路径怎么实现两个逻辑功能

  实例:登录模块

  进入登录页面和点击登录的请求路径都是一样的,只不过他们的请求方式不一样而已;这样我们在后台就只需要写一个视图函数来实现两个功能逻辑;进入登录页面的请求时GET请求,点击登录的请求是POST请求

 

2 后台如何利用一个视图函数实现不同的逻辑

  根据请求方式不同执行不同的逻辑

  利用 request 对象的属性来判断请求方式

    request.method    返回值时请求方式(GET/POST/HEAD/OPTIONS)

  2.1 编写一个简单的登录模块

    2.1.1 要求

      去往登录页面和点击登录的路径保持一致

      后台利用一个视图函数处理去往登录页面和点击登录按钮的请求

      如果是去往登录页面的请求就响应一个登录页面,如果是点击登录页面的请求就响应一个主页面并获取相关的登录数据

    2.1.2 编写连个HTML文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>主页面</title>
</head>
<body>
    <h2>庠序科技主页面</h2>
    <hr />
    <h4>Donot aim for your success if you really want it. Just stick to do what you love and believe in.</h4>
</body>
</html>
index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
</head>
<body>
    <h2>庠序科技登录页面</h2>
    <hr />
    <div>
        <form action="/login/" method="post">
            <div>
                <label for="email">邮箱:</label><input type="text" id="email" name="email" />
            </div>
            <div>
                <label for="password">密码:</label><input type="password" id="password" name="password" />
            </div>
            <div>
                <button type="submit">登录</button>
            </div>
        </form>
    </div>
</body>
</html>
login.html

    2.1.3 编写视图函数

from flask import Flask
from flask import request
from flask import render_template

from werkzeug.datastructures import ImmutableMultiDict

app = Flask(__name__)


@app.route(\'/\')
def index():
    return render_template(\'index.html\')

@app.route(\'/login/\', methods=[\'GET\', \'POST\'])
def login():
    if request.method == \'GET\':
        print(\'GET请求\')
        return render_template(\'login.html\')
    if request.method == \'POST\':
        print(\'POST请求\')
        formData = request.form
        print(type(formData))
        print(formData)
        email = formData.get(\'email\', \'null\')
        password = formData[\'password\']
        print("邮箱数据为:{},密码数据为:{}".format_map(email, password))

        return render_template(\'index.html\')

print(app.url_map)


if __name__ == \'__main__\':
    app.run(debug=True)
app.py

 

3 利用表单框架书写表单

  3.1 导入表单框架

    pip3 install -i https://pypi.doubanio.com/simple/ flask-wtf

   3.2 编写表单类

from flask_wtf import FlaskForm
from wtforms import Form
from wtforms import StringField, BooleanField

class LoginForm(Form):
    email = StringField()
    password = StringField()

loginForm = LoginForm() # 实例化一个LoginForm对象
print(loginForm.password.label) 
print(loginForm.email.label)
print(loginForm.email())
print(loginForm.data)
print(loginForm.errors)
测试form框架

  3.3 利用表单类去渲染模板

    3.3.1 准备

      从 flask_wtf 中导入 CSRFProtect    

        from flask_wtf import CSRFProtect as WTF       # 利用表单类去渲染模板时需要用到

       在 Flask对象 上注册一个 CSRFProtect

        WTF(app) # 在app上注册一个 WTF (所有的flask插件都必须进行注册)

      修改 Flask对象 的配置文件使得 WTF_CSRF_ENABLED 失效

        app.config.from_pyfile(\'config.py\') # 修改app的配置文件(使 WTF_CSRF_ENABLED 失效)

        config.py 文件中的信息为  WTF_CSRF_ENABLED = False

          详情请查看修改 Flask应用默认配置 先关内容

    3.3.2 利用表单类渲染模板的步骤

      》导入表单类

        from forms import LoginForm

      》创建一个表单类对象

        liginForm = LoginForm()

      》将这个表单对象传到模板中去

         render_template(\'login.html\', loginForm = liginForm)

      》利用表单对象的相关方法去渲染模板

        {{ loginForm.email.label }}:{{ loginForm.email() }}

          注意:loginForm.email.label 和  loginForm.email() 都是python表达式,他们的返回值是一个字符串

from flask import Flask
from flask import request
from flask import render_template
from flask_wtf import CSRFProtect as WTF # 利用表单类去渲染模板时需要用到

from forms import LoginForm

app = Flask(__name__)
WTF(app) # 在app上注册一个 WTF (所有的flask插件都必须进行注册)
app.config.from_pyfile(\'config.py\') # 修改app的配置文件(使 WTF_CSRF_ENABLED 失效)


@app.route(\'/\')
def index():
    return render_template(\'index.html\')

@app.route(\'/login/\', methods=[\'GET\', \'POST\'])
def login():
    if request.method == \'GET\':
        print(\'GET请求\')
        liginForm = LoginForm()
        return render_template(\'login.html\', loginForm = liginForm)

print(app.url_map)


if __name__ == \'__main__\':
    app.run(debug=True)
python代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
</head>
<body>
    <h2>庠序科技登录页面</h2>
    <hr />
    <div>
        <form action="/login/" method="post">
            <div>
                {{ loginForm.email.label }}:{{ loginForm.email() }}
            </div>
            <div>
               {{ loginForm.password.label }}:{{ loginForm.password() }}
            </div>
            <div>
                <button type="submit">登录</button>
            </div>
        </form>
    </div>
</body>
</html>
模板代码

 

  3.4 利用表单类获取数据

from flask import Flask
from flask import request
from flask import render_template
from flask_wtf import CSRFProtect as WTF # 利用表单类去渲染模板时需要用到

from forms import LoginForm

app = Flask(__name__)
WTF(app) # 在app上注册一个 WTF (所有的flask插件都必须进行注册)
app.config.from_pyfile(\'config.py\') # 修改app的配置文件(使 WTF_CSRF_ENABLED 失效)


@app.route(\'/\')
def index():
    return render_template(\'index.html\')

@app.route(\'/login/\', methods=[\'GET\', \'POST\'])
def login():
    if request.method == \'GET\':
        print(\'GET请求\')
        liginForm = LoginForm() # 相当于java中利用无参构造器创建对象
        return render_template(\'login.html\', loginForm = liginForm)
    if request.method == \'POST\':
        print(\'POST请求\')
        loginForm = LoginForm(request.form)  # 相当于java中利用有参构造器创建对象
        print(loginForm)
        email = loginForm.email.data
        password = loginForm.password.data
        print("邮箱为:{},密码为:{}".format(email, password))
        return render_template(\'index.html\')

print(app.url_map)


if __name__ == \'__main__\':
    app.run(debug=True)
View Code

  3.5 如何利用表单框架去验证获取到的表单数据格式

    3.5.1 在表单中为每个字段定义验证器

from flask_wtf import FlaskForm
from wtforms import Form
from wtforms import StringField, BooleanField # 导入用到的字段
from wtforms.validators import InputRequired, Length, Email # 导入用到的验证器

class LoginForm(FlaskForm): # 注意如果单独使用功能时要继承Form,如果在Flask框架中使用是要继承FlaskForm
    email = StringField(
        label=\'邮箱\', # 修改渲染时的value值
        validators=[ # 设定字段验证器
            InputRequired(\'邮箱是必填项\'),
            Email(\'邮箱格式错误\')
        ]
    )
    password = StringField(
        label=\'密码\',
        validators=[
            InputRequired(\'密码为必填项\'),
            Length(6, 9, \'密码长度为6到9\')
        ]
    )

# loginForm = LoginForm() # 实例化一个LoginForm对象
# print(loginForm.password.label)
# print(loginForm.email.label)
# print(loginForm.email())
# print(loginForm.data)
# print(loginForm.errors)
表单类

    3.5.2 在视图函数中利用表单对象去验证表单对象中的数据是否有效

    

  3.6 如何验证表单数据的合法性

    前提:已经从前端获取到用户数据的邮箱和密码数据

    思路:利用邮箱到数据库查询用户信息,如果有先关数据说明邮箱数据有效;通过邮箱查询到的用户信息中的密码数据和前端传过来的密码数据进行比较,如果相等就说明密码数据有效

    3.6.1 模拟一个数据模型来充当数据库

class User: # 模拟用户类
    def __init__(self, id, email, password, name):
        self.id = id
        self.email = email
        self.password = password
        self.name = name

    def check_password(self, password):
        return self.password == password

users = [ # 模拟用户数据
    User(\'1\', \'fury@163.com\', \'111111\', \'fury\'),
    User(\'2\', \'zeus@163.com\', \'222222\', \'zeus\'),
    User(\'3\', \'warrior@163.com\', \'333333\', \'warrior\')
]

# 根据用户ID去获取数据
def findById(userId):
    for user in users:
        if user.id == userId:
            return user
    else:
        return None

# 根据用户邮箱去获取数据
def findByEmail(email):
    for user in users:
        if user.email == email:
            return user
    else:
        return None
View Code

    3.6.2 调用相关方法判断表单数据是否有效

  

from flask import Flask
from flask import request
from flask import render_template
from flask_wtf import CSRFProtect as WTF # 利用表单类去渲染模板时需要用到

from forms import LoginForm

from models import findByEmail, findById

app = Flask(__name__)
WTF(app) # 在app上注册一个 WTF (所有的flask插件都必须进行注册)
app.config.from_pyfile(\'config.py\') # 修改app的配置文件(使 WTF_CSRF_ENABLED 失效)


@app.route(\'/\')
def index():
    return render_template(\'index.html\')

@app.route(\'/login/\', methods=[\'GET\', \'POST\'])
def login():
    if request.method == \'GET\':
        print(\'GET请求\')
        liginForm = LoginForm() # 相当于java中利用无参构造器创建对象
        return render_template(\'login.html\', loginForm = liginForm)
    if request.method == \'POST\':
        print(\'POST请求\')
        loginForm = LoginForm(request.form)  # 相当于java中利用有参构造器创建对象
        print(loginForm)
        if loginForm.validate():
            email = loginForm.email.data
            password = loginForm.password.data
            print("邮箱为:{},密码为:{}".format(email, password))
            user = findByEmail(email)
            if user:
                if user.check_password(password):
                    return render_template(\'index.html\')
                else:
                    return \'密码错误\'
            else:
                return \'该邮箱为注册\'

        else:
            return \'表单验证失败,错误信息 -> \' + str(loginForm.errors)

print(app.url_map)


if __name__ == \'__main__\':
    app.run(debug=True)
View Code

  3.7 如何实现在用户登录成功后进入主页面,并显示:欢迎XXX

    如果从前端获取到的登录数据判断为有效后,就将用户的名字信息添加到主页模板中,并渲染主页模板;如果用户没有登录就进入到主页面时会有登录和注册两个按钮

    

深入浅出Flask(20): H-ui前端框架的表单验证

python框架-flask05 表单

10gin快速入门

Flask表单

Flask 实现用户注册/登录表单

Flask WTForm 未验证,未报告表单错误