欢迎来到JIA的博客

3.flask框架-请求/响应

一、请求

1.1 请求的相关内容

文档: http://docs.jinkan.org/docs/flask/api.html#flask.request

  • request:flask中代表当前请求的 request 对象

  • 作用:在视图函数中取出本次请求数据

  • 导入from flask import request

  • 代码位置

  • 代理类 from flask.app import Request,

  • 源码类:from werkzeug.wrappers.Request

  • 父类:from werkzeug.wrappers.base_request

1.2 常用的属性

属性说明类型
data 记录请求体的数据,并转换为字符串 只要是通过其他属性无法识别转换的请求体数据 最终都是保留到data属性中 例如:有些公司开发小程序,原生IOS或者安卓,这一类客户端有时候发送过来的数据就不一样是普通的表单,查询字符串或ajax bytes类型
form 记录请求中的html表单数据 MultiDict
args 记录请求中的解析后的查询字符串,也可以是query_string MultiDict
cookies 记录请求中的cookie信息 Dict
headers 记录请求中的请求头 EnvironHeaders
method 记录请求使用的HTTP方法 GET/POST
url 记录请求的URL地址 string
files 记录请求上传的文件列表 *
json 记录ajax请求的json数据 json
query_string 记录请求中的原生查询字符串 bytes类型
path 获取本次客户端请求的路由路径部分[去掉域名端口] string

一些属性实例

from flask import Flask,request
# 限制客户端的http请求方法,注意这里与django不一样,flask并没有默认没有内置csrf攻击防范
@app.route(rule="/user", methods=["post","put","get","delete","patch"])
def user():
    # 例如:地址栏中通过  http://127.0.0.1:5000/user?user=1 返回本视图
    print(request.method) # 获取本次客户端的http请求方法         GET
    print(request.query_string)  # 获取本次客户端的查询字符串    b'user=1'
    print(request.path)  # 获取本次客户端请求的路由路径部分[去掉域名端口]    /user
    print(request.url) # 获取本次客户端请求的http url地址        http://127.0.0.1:5000/user?user=1
    # 直接从请求中取到请求方式并返回
    return request.method

1.3 常用属性实例

1.3.1 获取原生查询字符串

# 请求路径:POST 127.0.0.1:5000/args?username=xiaoming&pwd=123

print( request.query_string ) # b'username=xiaoming&pwd=123'

print( parse_qs( request.query_string.decode())) #{'username': ['xiaoming'], 'pwd': ['123']}

1.3.2 获取解析后的查询字符串

#请求路径:POST /args?username=xiaoming&pwd=123&lve=shoping&lve=game

print(request.args)
#ImmutableMultiDict([('username', 'xiaoming'), ('pwd', '123')]) 
#ImmutableMultiDict 是 一个有序字典,类似from collections import OrderedDict
print(request.args.get("username")) #xiaoming print(request.args.get("lve")) #shoping print(request.args.getlist("lve")) #['shoping', 'game']

1.3.3 获取解析后的查询字符串转化为普通字典

 #请求url:POST 127.0.0.1:5000/args?username=xiaoming&pwd=123&lve=shoping&lve=game

print(request.args.to_dict(flat=True)) # {'username': 'xiaoming', 'pwd': '123', 'lve': 'shoping'}
print(request.args.to_dict(flat=False)) # {'username': ['xiaoming'], 'pwd': ['123'], 'lve': ['shoping', 'game']}

1.3.4 表格、ajax 等发送数据的获取

@app.route(rule="/data",methods=["post","put","patch"])
def data():
    """接受客户端发送过来的原生请求体数据,是request.json,request.form,request.files
等无法接收的数据,全部会保留到这里,只要有方法获取就不会获取
""" print(request.data) # 接受表单提交的数据 print(request.form) # ImmutableMultiDict([('username', 'xiaoming'), ('password', '123456')]) print(request.form.get("username")) # 接收上传,files是一个列表 print( request.files ) # ImmutableMultiDict([('avatar', <FileStorage: 'hlw.jpg' ('image/jpeg')>)]) avatar = request.files.get("avatar") # ImmutableMultiDict([('avatar', <FileStorage: 'hlw.jpg' ('image/jpeg')>)]) print(avatar) # <FileStorage: 'hlw.jpg' ('image/jpeg')> # 接受ajax或其他客户端提交过来的json数据 print( request.json ) # {'username': 'xiaoming', 'password': '123456'} # 获取请求头信息 print() print() print( request.headers ) # 获取全部的而请求头信息 print( request.headers.get("Host") ) print( request.headers.get("Company")) # OldBoyEdu # 本次请求的url地址 print( request.url) # http://127.0.0.1:5000/data print( request.path ) # /data print( request.remote_addr ) # /127.0.0.1 return "hello"

总结实例:

from flask import Flask,request
from urllib.parse import parse_qs

from werkzeug.datastructures import ImmutableMultiDict

app = Flask(__name__)

@app.route("/args", methods=["POST"])
def args():
    """获取查询字符串 """
    # 获取原生查询字符串 query_string
    # print( request.query_string )
    # print( parse_qs( request.query_string.decode() ) )
    """POST 127.0.0.1:5000/args?username=xiaoming&pwd=123
    b'username=xiaoming&pwd=123'
    {'username': ['xiaoming'], 'pwd': ['123']}
    """
    # 获取解析后的查询字符串
    # print(request.args)
    # print(request.args.get("username"))
    # print(request.args.get("lve"))
    # print(request.args.getlist("lve"))
    """POST /args?username=xiaoming&pwd=123&lve=shoping&lve=game
    ImmutableMultiDict([('username', 'xiaoming'), ('pwd', '123')]) # ImmutableMultiDict 是 一个有序字典,类似from collections import OrderedDict
    xiaoming
    shoping
    ['shoping', 'game']
    """
    print(request.args.to_dict(flat=True))
    print(request.args.to_dict(flat=False))
    print(request.args)
    """POST 127.0.0.1:5000/args?username=xiaoming&pwd=123&lve=shoping&lve=game
    {'username': 'xiaoming', 'pwd': '123', 'lve': 'shoping'}
    {'username': ['xiaoming'], 'pwd': ['123'], 'lve': ['shoping', 'game']}
    """
    return "hello"

@app.route(rule="/data",methods=["post","put","patch"])
def data():
    """接受客户端发送过来的原生请求体数据,是request.json,request.form,request.files等无法接收的数据,全部会保留到这里"""
    print(request.data)

    # 接受表单提交的数据
    print(request.form) # ImmutableMultiDict([('username', 'xiaoming'), ('password', '123456')])
    print(request.form.get("username"))

    # 接收上传,files是一个列表
    print( request.files ) # ImmutableMultiDict([('avatar', <FileStorage: 'hlw.jpg' ('image/jpeg')>)])
    avatar = request.files.get("avatar")  # ImmutableMultiDict([('avatar', <FileStorage: 'hlw.jpg' ('image/jpeg')>)])
    print(avatar)  # <FileStorage: 'hlw.jpg' ('image/jpeg')>

    # 接受ajax或其他客户端提交过来的json数据
    print( request.json ) # {'username': 'xiaoming', 'password': '123456'}

    # 获取请求头信息
    print()
    print()
    print( request.headers ) # 获取全部的而请求头信息
    print( request.headers.get("Host") )
    print( request.headers.get("Company")) # OldBoyEdu

    # 本次请求的url地址
    print( request.url) # http://127.0.0.1:5000/data
    print( request.path ) # /data
    print( request.remote_addr ) # /127.0.0.1

    return "hello"

if __name__ == '__main__':
    app.run(host="0.0.0.0",port=5000,debug=True)
总结实例

 

二、响应

flask默认支持2种响应方式:

数据响应: 默认响应html文本,也可以返回 JSON格式,或其他格式

页面响应: 重定向

  url_for 视图之间的跳转

响应的时候,flask也支持自定义http响应状态码·

2.1 响应html文本

直接通过return返回html内容,视图执行以后的返回值会被路由进行判断数据类型,
 如果是字符串,路由内部会自动把视图的返回值作为参数传递给make_response,最终返回的都是response

from flask import make_response

@app.route("/")
def index():
    # [默认支持]响应html文本
    return "<img src='http://flask.pocoo.org/static/logo.png'>"
    return make_response("<h1>hello user</h1>") # 等同于上面的一段

2.2 返回JSON数据

在 Flask 中可以直接使用 jsonify 生成一个 JSON 的响应

 

from flask import Flask, request, jsonify
# jsonify 就是json里面的jsonify

@app.route("/")
def index():
    # 也可以响应json格式代码
    # data = {
    #     "id":1,
    #     "uname":"xiaoming"
    # }
    data = [
        {"id":1,"username":"liulaoshi","age":18},
        {"id":2,"username":"liulaoshi","age":17},
        {"id":3,"username":"liulaoshi","age":16},
        {"id":4,"username":"liulaoshi","age":15},
    ]
    return jsonify(data)

flask中返回json 数据,都是flask的jsonify方法返回就可以了.

2.3 响应其他数据格式

from flask import Flask,make_response,jsonify

app = Flask(__name__)

@app.route("/")
def index():
    """响应处理"""
    # 返回图片等其他自定义格式数据
    # with open("hlw.jpg", "rb") as f:
    #     content = f.read()
    # response = make_response(content)
    # response.headers["Content-Type"] = "image/jpg" # MIME type 类型
    # return response

    with open("myCode.zip","rb") as f:
        content = f.read()

    response = make_response(content)
    response.headers["Content-Type"] = "application/zip"
    return response

if __name__ == '__main__':
    app.run(host="0.0.0.0",port=5000,debug=True)

2.4  重定向

2.4.1 重定向到百度页面

from flask import redirect
# 页面跳转响应
@app.route("/user")
def user():
    # 页面跳转 redirect函数就是response对象的页面跳转的封装
    return redirect("http://www.baidu.com")
    # # redirect内部完成的事情如下:
    # from werkzeug.wrappers import Response
    # response = Response()
    # response.headers["Location"] = "http://www.baidu.com"
    # return response

2.4.2 重定向到自己写的视图函数

可以直接填写自己 url 路径

也可以使用 url_for 生成指定视图函数所对应的 url,通过redirect来完成跳转

from flask import url_for

url_for :根据视图函数名获取对应的url地址

from flask import Flask,redirect, url_for

app = Flask(__name__)

@app.route("/")
def index():
    """响应处理"""
    # 根据视图名称进行页面跳转
    # url_for 根据视图函数名获取对应的url地址
    url = url_for("user")
    print(url) # 仅仅是根据参数从app.url_map中提取对应的url地址 /user
    return redirect(url)

@app.route("/user")
def user():
    return "用户中心"

if __name__ == '__main__':
    app.run(host="0.0.0.0",port=5000,debug=True)

2.4.3 重定向到带有参数的视图函数

在 url_for 函数中传入路由参数

from flask import Flask,redirect, url_for

app = Flask(__name__)

@app.route("/")
def index():
    """响应处理"""
    # 根据视图名称进行页面跳转
    url = url_for("user",user_id=3)
    print(url) # 仅仅是根据参数从app.url_map中提取对应的url地址
    return redirect(url)

@app.route("/user/<user_id>")
def user(user_id):
    return f"用户中心,user_id={user_id}"

if __name__ == '__main__':
    app.run(host="0.0.0.0",port=5000,debug=True)

2.5 自定义状态码和响应头

在 Flask 中,可以很方便的返回自定义状态码,以实现不符合 http 协议的状态码,例如:status code: 666

@app.route('/demo4')
def demo4():
    # return 响应正文, 响应状态码[默认值:200] 
    # 适用于返回文本、json等格式
    return '权限不足!', 403
  
"""还可以使用make_response创建Response对象,然后通过response对象返回数据"""
from flask import make_response
@app.route("/rep")
def index7():
    response = make_response("ok")
    print(response)
    response.headers["Company"] = "oldboy" # 自定义响应头
    response.status_code = 201 # 自定义响应状态码
    return response

 

posted @ 2021-05-21 21:44  讷言敏行~  阅读(168)  评论(0编辑  收藏  举报