前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python-flask之路由及请求参数

python-flask之路由及请求参数

作者头像
Vincent-yuan
发布2023-02-26 19:28:34
1.3K0
发布2023-02-26 19:28:34
举报
文章被收录于专栏:Vincent-yuanVincent-yuan

简单示例如下

代码语言:javascript
复制
from flask import Flask
app = Flask(__name__)


@app.route('/hello')
def hello():
    return 'hello'


@app.route('/books')
def books():
    return 'books'


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

变量规则

上面的示例中,不论是/hello 还是 /books,URL都是固定的,

但URL可不都是固定的,比如/book/1/price 这种restful风格的URL,中间的1是某个book的id,如果用GET方法来请求这个URL,则表示希望获取id为1的book的价格。

这种URL的某一部分是变化的,这一次请求是/book/1/price,下一次请求或许会变成/book/21/price,你无法为每一个URL绑定一个处理函数。

为了解决这种情况,flask允许你在URL设置动态变化的部分,给URL添加变量部分,像/book/1/price 这种URL,就可以这样绑定

代码语言:javascript
复制
@app.route('/book/<int:id>/price')
def price(id):
    return str(id)

这种URL变量部分的规则为 <converter:variable_name> ,variable_name将作为参数传递给所绑定的函数,而且可以根据converter转换器对variable_name进行转换

converter转换器有下面几种

转换器

说明

int

接受整数

float

接受浮点数

path

接受带斜线的path

如果不标注转换器类型,则默认转为字符串,下面是这几种转换器的例子

代码语言:javascript
复制
# 不指定转换器
@app.route('/book/<name>/author')
def author(name):
    return name


# 转换器为int
@app.route('/book/<int:id>/price')
def price(id):
    return str(id)


# 转换器为float
@app.route('/book/price-ge/<float:price>')
def books_by_price(price):
    return str(price)


# 转换器为path
@app.route('/book/<path:book_info>')
def books_by_path(book_info):
    return book_info

启动服务,一次在浏览器里访问下面的URL来体会转换器的作用

  1. http://127.0.0.1:5000/book/python/author
  2. http://127.0.0.1:5000/book/13/price
  3. http://127.0.0.1:5000/book/price-ge/22.3
  4. http://127.0.0.1:5000/book/2019/09/sales

路由规则管理

添加路由规则,除了使用route装饰器外,还可以使用add_url_rule方法直接添加,下面两段代码在功能作用上是一样的

1、使用route添加路由规则

代码语言:javascript
复制
@app.route('/add_url')
def add_rule():
    return 'add url rule'

2、使用add_url_rule添加路由规则

代码语言:javascript
复制
def add_rule():
    return 'add url rule'


app.add_url_rule('/add_url', 'add_rule', add_rule)

在route装饰器中,调用了add_url_rule方法来添加路由规则,因此,他们最终的效果是一样的

设置method

http协议中,有很多种请求方法

一个URL,我们可以使用不同的方法来请求,在创建路由规则时,我们可以指定这个URL支持哪些请求方法

代码语言:javascript
复制
@app.route('/users', methods=['GET', 'POST'])
def users():
    return 'ok'

在route装饰器中设置methods,如果不设置该参数,则默认支持GET方法。

users函数既要处理GET请求,又要处理POST请求,那么如何区分它们呢? 这就要用到请求对象request

代码语言:javascript
复制
from flask import Flask, request
app = Flask(__name__)


@app.route('/users', methods=['GET', 'POST'])
def users():
    if request.method == 'GET':
        return 'get'
    if request.method == 'POST':
        return 'post'

    return 'ok'


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

flask请求对象request

request是flask框架的全局对象,你可以通过它来获得当前进入的请求数据,如果是在多线程环境下,flask可以保证你所使用的request对象就是当前这个线程所处理的请求。

既然request是请求对象,那么合理的猜测是通过它,我们可以获得当前请求的全部信息,例如请求的method,path, url, headers,cookies,请求的参数,请求的body.....

事实上也的确如此,下面的服务端代码和客户端代码,将互相配合向你演示如何使用request获得有关当前请求的重要信息

服务端代码

代码语言:javascript
复制
from flask import Flask, request
app = Flask(__name__)


@app.route('/users', methods=['GET', 'POST'])
def users():
    print(request.method)       # 请求方法
    print(request.headers)      # 请求的headers
    print(request.path)         # 资源路径
    print(request.url)          # 完整的url
    print(request.remote_addr)  # 客户端IP
    print(request.cookies)      # 请求的cookie
    return 'ok'


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

客户端代码

代码语言:javascript
复制
import requests

cookie_dict = {'name': 'python'}
res = requests.get('http://127.0.0.1:5000/users', cookies=cookie_dict)

使用客户端代码发出请求后,服务端程序会输出如下内容

代码语言:javascript
复制
GET              # 请求方法
Content-Type: 
Content-Length: 
Host: 127.0.0.1:5000
User-Agent: python-requests/2.22.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Cookie: name=python


/users          # 资源路径
http://127.0.0.1:5000/users     # 完整路径
127.0.0.1                       # 客户端ip
{'name': 'python'}              # 请求的cookie

提醒一点,request.remote_addr并不一定能够准确的获得客户端的IP,因为在部署服务时,通常最前端用nginx做转发,这样,你获得其实是nginx的IP地址,而非用户的真实地址

解析get请求参数

介绍flask如何解析http的get请求的参数, 解析post请求提交的表单和json数据,

get请求用于查询数据,通常会带有参数,参数放在path的后面,中间用问号连接,多个请求参数以key=value的形式用&连接起来,

下面是一个带参数的get请求的示例url

代码语言:javascript
复制
http://127.0.0.1:5000/users?name=poly&age=14

get请求的参数可以通过request.args来获得,也可以通过request.values来获得

下面是使用方法示例

代码语言:javascript
复制
@app.route('/users', methods=['GET', 'POST'])
def users():
    name = request.args['name']
    age = request.args['age']
    print(name, age)
    return 'ok'

需要注意的是,获取到的参数一律都是字符串类型,使用时需要你自己做类型转换

获得post请求表单数据

post请求用于新增数据,

它提交数据的格式有两种,一种是form表单,一种是json数据,

requests.form里存储着post请求提交的form表单数据,

下面是解析示例

代码语言:javascript
复制
@app.route('/users', methods=['POST'])
def users():
    name = request.form['name']
    age = request.form['age']
    print(name, age)
    return 'ok'

使用request.values

不论是request.args, 还是request.form,其类型都是MultiDict,

因此,flask又提供了一个request.values,类型为CombinedMultiDict,它包含了args和form,

这样,在获取数据时,就不必在纠结到底用args还是用form了,request.values使用方法与args,form相同

获得json数据

客户端的post请求,put请求,有可能提交的是json数据,而非form表单数据,

post提交的json数据,不能通过args,form.values来获取,而是要用get_json()方法来获取

服务端示例代码

代码语言:javascript
复制
@app.route('/users', methods=['POST'])
def users():
    data = request.get_json()
    print(data)
    return 'ok'

客户端示例代码

代码语言:javascript
复制
import requests

res = requests.post('http://127.0.0.1:5000/users', json={'name': 'poly', 'age': 13})

参考:http://www.coolpython.net/flask_tutorial/basic/flask-parse-request-data.html

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-02-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 变量规则
  • 路由规则管理
  • 设置method
  • flask请求对象request
  • 解析get请求参数
  • 获得post请求表单数据
  • 使用request.values
  • 获得json数据
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档