Flask一:安装初始,return方式,Request,Jinja2,session

一:安装和初始

1.Flask 安装 + 启动
	from flask import Flask
	app = Flask(__name__)  # 实例化flask对象  # __name__   多app应用,分区实例在哪个文件中
	app.run()
	
	高级启动:
	from flask import Flask
	app = Flask(__name__)

	@app.route("/") # app中的rotue装饰器
	def home():  # 视图函数
		return "Hello World!"

	app.run()


二: Render, Redirect HttpResponse

2.Flask Response
	1.HttpResponse("HelloWorld")	"HelloWorld" 返回字符串
	from flask import render_template 默认存放路径 templates
	2.render("模板路径")		render_template 返回模板
	from flask import redirect 重定向
	3.redirect("/") 
	
	Flask 中的返回特殊封装 2个
	1.jsonify	转换标准JSON格式
		响应头中加入 Content-type:application/json
		在Flask 1.1.1 版本中 加入了 直接返回字典 可以不再使用jsonify了
	
	2.send_file	发送文件
		打开并返回文件内容,
		自动识别文件类型,
		响应头中加入Content-type:文件类型    # Content-Type: audio/mpeg
		ps:当浏览器无法识别Content-type时,会下载文件
            
     # 大的视频文件是 分段式请求 
     # 打开并返回文件内容,自动识别文件类型,content-type:文件类型
        
     # Ps:
     # 浏览器无法识别content-type时,都以下载返回。   识别的话,直接打开


from flask import Flask, render_template, redirect, jsonify, send_file

# Alt + 回车 快速的导入模块


app = Flask(__name__)  # 实例化flask对象  # __name__   多app应用,分区实例在哪个文件中

app.config["DEBUG"] = True  # 能够随时更改自动重启,不加的话每次更改代码需要手动重启


@app.route("/") # app中的rotue装饰器
def home():    # 视图函数
    # return 1
    # TypeError: The view function did not return a valid response.
    # The return type must be a string, dict, tuple, Response instance, or WSGI callable, but it was a int.

    return "home"


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


@app.route("/reback")
def reback():
    return redirect('/index')


@app.route("/json")
def my_jsonify():
    # return jsonify({"a":1})
    return {"k": "v"}


@app.route("/myfile")
def my_file():
    # return send_file('1chushi.py')
    # return send_file('1.jpg')
    return send_file('ss.mp3')

# 传文件
# 不管video还是audio都是显示 Audio 

app.run()



三:Request

3.Flask Request
假登录
405 请求方式不被允许 - GET请求可以 POST请求 405 Method Not Allowed
Form表单 - FormData 
f orm - 表单

from flask import request 公共对象

1.request.form 获取FormData中的数据 - Form表单
2.request.args # 获取URL中的参数
3.request.files # 获取FormData中的文件数据

print(request.url) # 获取访问路径
print(request.method) # 获取请求方式
print(request.path) # 路由地址 /login
print(request.values) # Form 和 Args 中的数据
# 综合获取 X
print(request.args.get("id")) # 获取URL中的参数
print(request.args["id"]) # 获取URL中的参数
print(request.args.to_dict()) # 获取URL中的参数 转换成 字典

print(request.environ) # 获取请求原始信息
print(request.base_url) # 获取URL头,不包含参数

print(request.json) # 毁三观 1 请求头中 Content-type:application/json 数据序列化 request.json
print(request.data) # 毁三观 2 请求头中 Content-type 不包含 Form or data

print(request.headers) # 请求头中的数据

3.1:request.py

from flask import Flask, render_template, request
import os

app = Flask(__name__)
app.config["DEBUG"] = True  # 能够随时更改自动重启,不加的话每次更改代码需要手动重启



@app.route("/login", methods=["POST", "GET"])
def login():
    if request.method == "GET":
        
        print(request.url) # 获取访问路径
        # request.url: http://127.0.0.1:5000/login
        # request.url: http://127.0.0.1:5000/login?id=1

        print(request.method) # 获取请求方式
        # GET
        # GET

        print(request.path) # 路由地址 /login
        # /login
        # /login

        print(request.values) # 可以获取URL中的参数 也可以获取 FormData中的数据
        # 综合获取 ,可以获取url 和 formdata的数据
        # CombinedMultiDict([ImmutableMultiDict([]), ImmutableMultiDict([])])
        # CombinedMultiDict([ImmutableMultiDict([('id', '1')]), ImmutableMultiDict([])])


        print(request.args)
        # ImmutableMultiDict([('id', '1')])


        print(request.args.to_dict()) # 获取URL中的参数 转换成 字典
        # {}
        # {'id': '1'}

        print(request.args.get("id")) # 获取URL中的参数
        # None 没有参数的时候就是None
        # 1

        # print(request.args["id"]) # 获取URL中的参数
        # 1
        # 字典索引取不到值的时候 ,会出现keyerror



        print(request.environ) # 获取请求原始信息
        # {'wsgi.version': (1, 0), 'wsgi.url_scheme': 'http', 'wsgi.input': <_io.BufferedReader name=1140>, 'wsgi.errors': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>, 'wsgi.multithread': True, 'wsgi.multiprocess': False, 'wsgi.run_once': False, 'werkzeug.server.shutdown': <function WSGIRequestHandler.make_environ.<locals>.shutdown_server at 0x000001F2C1CD8378>, 'SERVER_SOFTWARE': 'Werkzeug/0.15.4', 'REQUEST_METHOD': 'GET', 'SCRIPT_NAME': '', 'PATH_INFO': '/login', 'QUERY_STRING': '', 'REQUEST_URI': '/login', 'RAW_URI': '/login', 'REMOTE_ADDR': '127.0.0.1', 'REMOTE_PORT': 14611, 'SERVER_NAME': '127.0.0.1', 'SERVER_PORT': '5000', 'SERVER_PROTOCOL': 'HTTP/1.1', 'HTTP_HOST': '127.0.0.1:5000', 'HTTP_CONNECTION': 'keep-alive', 'HTTP_CACHE_CONTROL': 'max-age=0', 'HTTP_UPGRADE_INSECURE_REQUESTS': '1', 'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36', 'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate, br', 'HTTP_ACCEPT_LANGUAGE': 'zh-CN,zh;q=0.9,en;q=0.8', 'HTTP_COOKIE': 'sessionid=wnuu61vo39ha2rnhjly8tturem306js3; csrftoken=dBlvd2yERl2dy9Oe7JoPLWer7aaOf35nx83lvoruaY0NOkl3T747KlIo5YwZ7026', 'werkzeug.request': <Request 'http://127.0.0.1:5000/login' [GET]>}

        print(request.base_url) # 获取URL头,不包含参数
        # http://127.0.0.1:5000/login

        print(request.json) # 毁三观 1 请求头中 Content-type:application/json 数据序列化 request.json
        # None

        print(request.data) # 毁三观 2 请求头中 Content-type 不包含 Form or data
        # b''

        print(request.headers) # 请求头中的数据
        # Host: 127.0.0.1:5000
        # Connection: keep-alive
        # Cache-Control: max-age=0
        # Upgrade-Insecure-Requests: 1
        # User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36
        # Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
        # Accept-Encoding: gzip, deflate, br
        # Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
        # Cookie: sessionid=wnuu61vo39ha2rnhjly8tturem306js3; csrftoken=dBlvd2yERl2dy9Oe7JoPLWer7aaOf35nx83lvoruaY0NOkl3T747KlIo5YwZ7026
        
        return render_template("login.html")

    if request.method == "POST":

        
        print(request.method)
        # POST



        print(request.form)
        # Multidict  多重字典,得到字典套列表套元组的类型
        # ImmutableMultiDict([('username', '123'), ('pwd', '456')])

        print(request.form.to_dict())
        # {'username': '123', 'pwd': '456'}



        print(request.values) # 可以获取URL中的参数 也可以获取 FormData中的数据
        # CombinedMultiDict([ImmutableMultiDict([]), ImmutableMultiDict([('username', '123'), ('pwd', '456')])])

        print(request.values.to_dict())
        # {'username': '123', 'pwd': '456'}



        print(request.json) # 毁三观 1 请求头中 Content-type:application/json 数据序列化 request.json
        # None

        print(request.data) # 毁三观 2 请求头中 Content-type 不包含 Form or data 原始请求体数据
        # b''


        print(request.headers)
        # Host: 127.0.0.1:5000
        # Connection: keep-alive
        # Content-Length: 235
        # Cache-Control: max-age=0
        # Origin: http://127.0.0.1:5000
        # Upgrade-Insecure-Requests: 1
        # Content-Type: multipart/form-data; boundary=----WebKitFormBoundary1BWoxZMCbTbU3Koy
        # User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36
        # Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
        # Referer: http://127.0.0.1:5000/login
        # Accept-Encoding: gzip, deflate, br
        # Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
        # Cookie: sessionid=wnuu61vo39ha2rnhjly8tturem306js3; csrftoken=dBlvd2yERl2dy9Oe7JoPLWer7aaOf35nx83lvoruaY0NOkl3T747KlIo5YwZ7026

        # print(request.files.get("my_file"))
        #
        # my_file = request.files.get("my_file")
        # # fp = os.path.join("templates",my_file.filename)
        # my_file.save(my_file.filename)
        

        # 获取文件的数据

        print(request.files)
        # ImmutableMultiDict([('my_file', <FileStorage: '1.jpg' ('image/jpeg')>)])
        # 文件只在File 里显示
        # Form中不包含

        print(request.files.get("my_file"))
        # <FileStorage: '1.jpg' ('image/jpeg')>

        my_file = request.files.get("my_file")
        # my_file.save(my_file.filename)
        # 保存到本地的

        # 可以指定路径 用os模块
        fq = os.path.join("templates", my_file.filename)
        my_file.save(fq)

        username = request.form.get("username")
        password = request.form["pwd"]
        # Get 和索引都能拿到值

        if username == "123" and password == "456":
            return "登录成功"
        else:
            return "登录失败"


# 如果包导入的话,if __name__下面不会执行
if __name__ == '__main__':
    app.run()

3.2:login.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
    <link rel="stylesheet" href="bootstrap-3.3.7-dist/css/bootstrap.min.css">

</head>
<body>

<form action="/login" method="post" enctype="multipart/form-data">
    用户名: <input type="text " name="username">
    密码: <input type="password" name="pwd">
    <input type="file" name="my_file">
    <input type="submit">
</form>



<script src="jquery-3.4.1.js"></script>
<script>

</script>
</body>
</html>


四:Jinja2和高级用法

		
4.Jinja2
{{}} 引用 or 执行
{%%} 逻辑语法 if else for

4.1:jinja2.py

from flask import Flask, render_template,request,redirect,Markup

STUDENT = {'name': 'Ivan', 'age': 38, 'gender': '中'}

STUDENT_LIST = [
    {'name': 'Sail', 'age': 38, 'gender': '中'},
    {'name': 'Ivan', 'age': 73, 'gender': '男'},
    {'name': 'VS', 'age': 84, 'gender': '女'}
]

STUDENT_DICT = {
    1: {'name': 'Sail', 'age': 38, 'gender': '中'},
    2: {'name': 'Ivan', 'age': 73, 'gender': '男'},
    3: {'name': 'VS', 'age': 84, 'gender': '女'},
}

app = Flask(__name__)
app.config["DEBUG"] = True


@app.template_global()
# 把ab函数传到前端了
def ab(a,b):
    return a+b



@app.route("/jija")
def jija():
    my_in = Markup("<input type='text' name='uname'>")
    return render_template("jija.html",
                           stu_info=STUDENT,
                           stu_list=STUDENT_LIST,
                           stu_dict=STUDENT_DICT,
                           m=my_in
                           )


if __name__ == '__main__':
    app.run("127.0.0.1", 9999)

4.2:jinja2.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{{ stu_info }}

<table border="1px">
    <tr>
        <td>name</td>
        <td>age</td>
        <td>gender</td>
    </tr>
    <tr>
        <td>{{ stu_info.name }}</td>
        <td>{{ stu_info.get("age") }}</td>
        <td>{{ stu_info["gender"] }}</td>
    </tr>

</table>

<br/>

{{ stu_list }}

<table border="1px">
    <tr>
        <td>name</td>
        <td>age</td>
        <td>gender</td>
    </tr>

```
{% for foo in stu_list %}
    <tr>
        <td>{{ foo.name }}</td>
        <td>{{ foo.get("age") }}</td>
        <td>{% if foo["gender"] !="男" and foo["gender"] !="女" %}
            女
            {{ foo["gender"] }}
        {% endif %}

        </td>
    </tr>
{% endfor %}
```

</table>
<br/>

{{ stu_dict }}

<table border="1px">
    <tr>
        <td>id</td>
        <td>name</td>
        <td>age</td>
        <td>gender</td>
    </tr>
    <tr>
        {% for id,s in stu_dict.items() %}
            <td>{{ id }}</td>
            <td>{{ s.name }}</td>
            <td>{{ s.get("age") }}</td>
            <td>{{ s["gender"] }}</td>
            </tr>
        {% endfor %}

</table>

<br/>
{{ m }}

<br/>
{% macro my_input(na,ty) %}
    <input type="{{ ty }}" name="{{ na }}">
{% endmacro %}

{{ my_input("uname","text") }}       #  macro 需要启动才生产输入框



<br/>
{#{{ ab(1,2) }}#}

</body>
</html>




五:session

5.Flask中的Session 不是三方组件 //Flask-Session
from flask import session

session 交由客户端保管机制
# eyJ1c2VybmFtZSI6IjEyMyJ9.XSVpHA.W0NfiCmW-lsTV0mvQI7mx2mf1Wo
# .eJyrViotTi3KS8xNVbJSMjQyVtKBCxhiiBhhiBhjiJhgiJhiiJhBRWoBMFYkPg.XSVsaA.9merwNdTg3ZkZrdTumYRG7x8x7Y
# .eJyrViotTi3KS8xNVbJSMjQyVtKBCxhiiBhhiBhjiJhgiJhiiJhBRWoBMFYkPg.XSVsvg.6OqcN7CR6nrT2BtE-w1kBAr3xPo
# .eJxNzL0OgCAMBOB36exAoRTjs7jwUzcdNEzGdxckMV1u-e7uhnrJecRdYIG1eqS5pWCB6RccZDGtlQSjIvsRBxtbwZEmN8gZ21czK6JBiamtQhZF_qPAuR-WookH-dQO_WYiPC-8zDp8.XSVtLw.7I-z1bsqiWFln3cipbrVOpEE33g

反序列化机制 - 
当客户端发起请求 - request 带上 Cookie - Cookie中有session的加密字符串 - Flask 收到Session加密字符串 - 通过secret_key解密session的加密字符串 - 获得 {username:123}

序列化机制 - 开启session - session["username"] = uname
先创建一个字典 {username:123} 接下来 通过secret_key + 时间戳 + 签名 加密 形成
# eyJ1c2VybmFtZSI6IjEyMyJ9.XSVpHA.W0NfiCmW-lsTV0mvQI7mx2mf1Wo session的加密字符串

5.1:session.py

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

app = Flask(__name__)
app.debug = True
app.secret_key = "adfnaskjfnakjs"

STUDENT = {'name': 'Old', 'age': 38, 'gender': '中'}

STUDENT_LIST = [
    {'name': 'Old', 'age': 38, 'gender': '中'},
    {'name': 'Boy', 'age': 73, 'gender': '男'},
    {'name': 'EDU', 'age': 84, 'gender': '女'}
]

STUDENT_DICT = {
    1: {'name': 'Old', 'age': 38, 'gender': '中'},
    2: {'name': 'Boy', 'age': 73, 'gender': '男'},
    3: {'name': 'EDU', 'age': 84, 'gender': '女'},
}


@app.route("/login", methods=["POST", "GET"])
def login():
    if request.method == "GET":
        return render_template("login.html")

    uname = request.form.get("username")
    pwd = request.form.get("pwd")

    if uname == '123' and pwd == '123':
        session['username'] = uname
        return "登陆成功"
    else:
        return "登录失败"


@app.route("/detail")
def detail():
    if session.get("username"):
        return render_template("jija.html",
                               stu_info=STUDENT,
                               stu_list=STUDENT_LIST,
                               stu_dict=STUDENT_DICT, )

    else:
        return redirect("/login")


if __name__ == '__main__':
    app.run("127.0.0.1", 9999)





5.2:login.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
    <link rel="stylesheet" href="bootstrap-3.3.7-dist/css/bootstrap.min.css">

</head>
<body>

<form action="/login" method="post" enctype="multipart/form-data">
    用户名: <input type="text " name="username">
    密码: <input type="password" name="pwd">
    <input type="file" name="my_file">
    <input type="submit">
</form>



<script src="jquery-3.4.1.js"></script>
<script>

</script>
</body>
</html>




原文地址:https://www.cnblogs.com/Quantum-World/p/11166227.html