flask中的CBV , flask-session在redis中存储session , WTForms数据验证 , 偏函数 , 对象里的一些小知识

flask中的CBV , flask-session在redis中存储session , WTForms数据验证 , 偏函数 , 对象里的一些小知识
 
flask中的CBV写法
后端代码
# 导入views
from flask import Flask, render_template, views, request
 
app = Flask(__name__)
 
 
# CBV写法
class Login(views.MethodView):       # 定义一个类,不用装饰器,继承了MethodView就不用写methods=['GET', 'POST']了
    def get(self):                                                # 函数就是类里面的方法
        return render_template("login.html")     # get请求进来返回login页面
 
    def post(self): # post请求
        my_file = request.files.get("MyFile")    # 用request取出MyFile(MyFile是前端页面选取的文件),然后赋值给my_file
        my_file.save(my_file.filename) # 把选取的文件保存下下来
        return "123"
 
app.add_url_rule("/login", view_func=Login.as_view(name='login'))
 
if __name__ == '__main__':
    app.run("0.0.0.0", 9527, debug=True)
前端代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="" method="post" enctype="multipart/form-data">
    <input type="text" name="username">
    <input type="file" name="MyFile">
    <input type="submit" value="登录">
</form>
</body>
</html>
 
 
 
flask-session在redis中存储session
后端代码
from flask import Flask, request, render_template, session
from flask_session import Session
from redis import Redis
 
# flask-session在redis中存储session
app = Flask(__name__)
app.config["DEBUG"] = True
app.config["SESSION_TYPE"] = "redis"  # session存储格式为redis
app.config["SESSION_REDIS"] = Redis(host="127.0.0.1", port=6379)  # redis的服务器参数, ip 和 端口
app.config["SESSION_COOKIE_NAME"] = "#¥%……&*(#E$RTY$%RTY%^Y&U%^&*"
 
Session(app)
 
 
@app.route("/login", methods=["GET", "POST"])
def login():
    if request.method == "GET":
        return render_template('login.html')
    else:
        session['user'] = request.form.get('username')
        return str(session['user'])
 
 
if __name__ == '__main__':
    app.run()
前端代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="" method="post" enctype="multipart/form-data">
    <input type="text" name="username">
    <input type="file" name="MyFile">
    <input type="submit" value="登录">
</form>
</body>
</html>
 
 
 
WTForms
        WTForms是一个支持多个web框架的form组件,主要用于对用户请求数据进行验证。
 
登录和注册验证 例:
from flask import Flask, request, render_template, session
from flask_session import Session
from redis import Redis
from wtforms import Form, validators, widgets
from wtforms.fields import simple, core
 
 
app = Flask(__name__)
app.config["DEBUG"] = True
app.config["SESSION_TYPE"] = "redis"  # session存储格式为redis
app.config["SESSION_REDIS"] = Redis(host="127.0.0.1", port=6379)  # redis的服务器参数, ip 和 端口
app.config["SESSION_COOKIE_NAME"] = "#¥%……&*(#E$RTY$%RTY%^Y&U%^&*"
 
Session(app)
 
 
# 登录错误提示类
class LoginForm(Form):
    username = simple.StringField(
        label='用户名',
        validators=[
            validators.DataRequired(message='用户名不能为空'),
            validators.Length(min=4, max=8, message='用户名必须大于等于4,小于等于8')
        ]
    )
 
    password = simple.PasswordField(
        label='密码',
        validators=[
            validators.DataRequired(message='密码不能为空'),
            validators.Length(min=4, max=8, message='密码长度必须大于等于4,小于等于8')
        ]
    )
 
 
# 登录校验代码
@app.route("/login", methods=["GET", "POST"])
def login():
    login_form = LoginForm()
    if request.method == "GET":
        return render_template('login.html', lf=login_form)
    else:  # 这里就相当于是post请求了
        login_form_data = LoginForm(request.form)  # request.form中的form就是formdata ,就是前段页面提交过来的数据,把数据序列化给login_form_data
        if login_form_data.validate():  # 校验数据
            session['user'] = login_form_data.data.get('username')  # 校验成功后从data中拿数据
            return str(session['user'])
        else:  # 如果校验失败,返回下面内容(lf  错误的数据)
            return render_template('login.html', lf=login_form_data)
 
 
# 注册错误提示或限制类
class RegForm(Form):  # 继承Form
    username = simple.StringField(
        label='用户名',
        validators=[
            validators.DataRequired(message='用户名不能为空')
        ],
        render_kw={'class': "my_class"}
    )
 
    password = simple.PasswordField(
        label='密码',
        validators=[
            validators.Length(min=6, max=16, message='密码长度应该大于或等于6,小于或等于16')
        ]
    )
 
    repassword = simple.PasswordField(
        label='确认密码',
        validators=[
            validators.EqualTo('password', message='两次密码不一致')
        ]
    )
 
    gender = core.SelectField(
        label='性别',
        choices=(
            (1, '女'),
            (2, '男')
        ),
        default=1,
        render_kw={'class': 'my_class'},
        coerce=int
    )
 
    email = simple.StringField(
        label='邮箱',
        validators=[
            validators.DataRequired(message='邮箱不能为空'),
            validators.Email(message='不符合规定')
        ]
    )
 
    hobby = core.SelectMultipleField(
        label='爱好',
        choices=(
            (1, '萝莉'),
            (2, '小阿姨'),
            (3, '大姐姐'),
            (4, '小姐姐')
        ),
        coerce=int,
        default=(1, 4)
    )
 
 
# 注册校验代码
@app.route('/reg', methods=['GET', 'POST'])
def reg():
    if request.method == 'GET':         # 此时是'GET'请求
        rf = RegForm()      # 把RegForm这个类赋值给rf , 此时这个类里面是没有数据的,因为还没有注册,只是一个注册的前端页面
        return render_template('reg.html', rf=rf)       # 跳转到reg.html , 带上rf填充注册的前端页面
    else:       # 'POST'请求的时候
        rf_data = RegForm(request.form)     # 这里取出来的就是formData数据,把数据交给rf_data
        if rf_data.validate():              #校验数据
            # print(rf_data.data.get('hobby'))
            # print(type(rf_data.data.get('gender')))
            return '注册成功'             # 校验通过返回这个HttpResponse
        else:
            return render_template('reg.html', rf=rf_data)      # 校验不通过还是跳转到注册页面,不同的是带上了错误信息
 
 
if __name__ == '__main__':
    app.run()
 
 
偏函数
# 偏函数
from functools import partial
 
 
def my_sum(a, b):
    print(a)
    print(b)
    return a + b
 
 
# 注意: 依然遵守传参规范,位置参数不能不能出现在关键字参数后面
# new_my_sum = partial(my_sum, 10, b=20)
new_my_sum = partial(my_sum, 10)  # 按位置传参这个10传给a了, b的参数也能在这里传(my_sum, 10, 20),这里如果传了两个参数了那么 res = new_my_sum(20)这里就不用传参了
 
# 此时的new_my_sum里面应该是下面这样的
# new_my_sum
# def my_sum(b):
#     a = 10
 
# 上面如果把两个参数都传了这里就不用传参了
# res = new_my_sum()
res = new_my_sum(20)  # 此时a已经有参数了,这个20就传给b了
print(res)  # res接收return返回的值
 
 
对象里面的一些小知识
class MyClass(object):
    def __call__(self, *args, **kwargs):
        print(666)
 
    def __setattr__(self, key, value):
        print(key, value)
 
    def __getattr__(self, item):
        print(item)
 
    def __setitem__(self, key, value):
        print(key, value, 'item')
 
    def __getitem__(self, item):
        print(item, 'item')
 
 
def func():
    return 123
 
 
a = MyClass()  # 类名加括号是实例化一个对象
# a()                # 对象加括号执行了类里面的__call__方法
 
# a.name = '小昭'
# a['name'] = '小昭'    # 添加item通过 对象,中括号 用的是 __setitem__ 方法
# a["my name is name"]  # 取item 通过 对象,中括号,索引 用的是 __getitem__ 方法
 
# a.name = "赵丽颖"    # 通过 对象 . 的方式添加item用的是 __setattr__ 方法
# a.mynameissetattr   # 通过 对象 . 的方式取item用的是 __getattr__ 方法
 
 

猜你喜欢

转载自www.cnblogs.com/hdy19951010/p/10447222.html
今日推荐