Day 14 Flask 传入参数

在网页中不可能只是按照设定好的 URL 去取得网页页面,在许多时候都需要带入不同的参数去取得不同的资料,所以这篇就要来讲一下如何接收传入的参数。

URL

参数位於 URL 的路径中,需要从 URL 中间抓参数的,可以使用这个方式:

# 提醒一下,这边的<>是需要带入的
@app.route('/<type:name>')
def <function name>(<name>):
    # TODO

其中 name 是必要的,下方的 function 内要使用必须在括号内填入名称,type 跟 : 不一定需要(冒号後面不可以有空格)。而类型有下列 5 种:

Type Description
string 文字类型(默认类型)
int 整数
float 浮点数
path 跟 string 差不多,但可以有斜线 /
uuid UUID 字符串
@app.route('/home/<username>')
def home_page(username):
    return f"Hello {username}"

@app.route('/add/<int:a>/<int:b>')
def add(a, b):
    return str(a + b)

如果要测试的话,就在 POSTMAN 或浏览器中输入 http://localhost:5000/home/Mike or http://localhost:5000/add/1/2 ,这样你就会的到回传的值,当然也可以把那个位置的参数换掉一样会得到相应的结果。

大概就是这样。

request

因为有些参数例如帐号密码直接写在 URL 上并不好,或是连结必须跟着不同使用情况跟着改变也不方便,所以这种情况必须采用其他方式传输参数。

那要怎麽传输资料跟取得资料呢?

首先要 import request(from flask import request),然後根据不同传输参数的方式,去使用相应的方法取得资料。这边先介绍两种最基本的传输参数的方式以及它们个别取资料的方法,还有一个超好用的通用取参数方式。

GET / args

第一个是最最常用传输的方式就是 GET,传输参数的方式就是在 URL 後面加上问号 ? 後,再加上 key=value,如果有多笔资料,则用 and & 连接起来(POSTMAN 可以在 Day 12 中间的蓝色区域选择 Params 然後输入 key 与 value)。

程序的部分需要这样子写:

# 记得 from flask import request
@app.route('/get-value', methods=['GET'])
def get_value():
    # 方法 1
    return request.args['input_value']

    # 方法 2, 不带预设值
    return request.args.get('input_value')
    
    # 方法 2, 带预设值
    return request.args.get('input_value', 'No input')

上下两种方式都可以使用,不过下面的方式可以在没有接到输入时能够有个预设值。

如果要测试的话,就在 POSTMAN 的 URL 输入 http://localhost:5000/get-value ,然後在中间(再说一次,选 Params)的输入参数部分 key 输入 input ,value 输入 test (其实这两个叫啥都可以,key 跟程序里面写得对的上就好,value 随便填),然後按 Send ,就会得到回传结果。

第一种方式虽然不需要改变基本的 URL (? 前面那陀),但是带的参数还是跟在 URL 的後面,若是需要传送一些比较机的资料还是不好,所以就有了这个方式。

POST / from

第二种方式是 POST ,这个方式是不会将传输的资料直接写在 URL 上面,不过就无法通过浏览器输入 URL 的方式测试结果了,需要再 POSTMAN 中选择 Body -> form-data 输入 key 与 value。

程序的部分需要这样子写:

@app.route('/post-value', methods=['POST'])
def post_value():
    # 方法 1
    return request.args['input_value']

    # 方法 2, 不带预设值
    return request.args.get('input_value')
    
    # 方法 2, 带预设值
    return request.form.get('input_value', 'No input')

跟前面一样,都可以使用,方法 2 一样可以带预设值。

如果要测试的话,就在 POSTMAN 的 URL 输入 http://localhost:5000/post-value ,然後在中间(使用 POST 记得选 Body -> x-www-form-urlencoded)的输入参数部分 key 输入 input ,value 输入 test (其实这两个叫啥都可以,key 跟程序里面写得对的上就好,value 随便填),然後按 Send ,就会得到回传结果。

any / values

最後要介绍一个超级大好用的方式,不管 GET 还是 POST 还是什麽(对,不只这两种方式,但要详细介绍的话又可以开另一篇了,之後讲 RESTful 会快速介绍过一遍)都可以接到,那就是 values (要有 s)。

@app.route('/any-value', methods=['GET', 'POST'])
def any_value():
    # 方法 1
    return request.values['input_value']

    # 方法 2, 不带预设值
    return request.values.get('input_value')
    
    # 方法 2, 带预设值
    return request.values.get('input_value', 'No input')

跟前面一样,都可以使用,方法 2 一样可以带预设值。

这个方法超好用,不管是使用哪种方式传值都可以接到。例如 GET 传值:

POST 传值:

*如果需要判断传值方式可以使用 request.method == '<method>' 来判断

JSON

除了上面这几种传值方式之外,还有一种也很常用的传值方式就是 JSON,尤其常用在传递大量参数上。那麽要如何使用以及处里呢?

首先,先来看程序部分:

@app.route('/JSON-value', methods=['POST'])
def JSON_value():
    # 判断是不是 JSON
    # 根据 HTTP Header 的 Content-Type 有无 application/json
    if request.is_json:
        # 解析 JSON 资料为 dict ,若不是 JSON,则返回 None
        data = request.get_json()
        # 从资料中获取值
        result = data.get('input_values', None)
    else:
        result = 'Not JSON Data'
    return result

接着在 POSTMAN 输入 URL http://localhost:5000/JSON-value、选择 POST、选择 Body -> rawTextJSON 、在中间的框内输入:

{
    "input_value": "test"
}

最後再按下 Send,就可以看到回传了输入的值。

url_for

上一篇有讲到可以使用 url_for 取代掉长长的网址对吧,那如果要带参数的话要怎麽办?其实 url_for 是可以带参数的,不过只能用在 URL 位置中跟 GET 方法,

# URL path parameter
url_for('home_page' , username='Mischau')

# GET method pass value
url_for('get-value', input_value='test input')

url_for 大概就这样。

File upload

如果希望使用者传递的不只是参数,还可以是档案(档案的话只能使用 POST 上传喔)。那这时候要怎麽做呢?直接看做法:

from flask import Flask, request
from werkzeug.utils import secure_filename
import os


CONFIGS = {
    'ENV': 'development',
    'DEBUG': True,
    'UPLOAD_FOLDER' = './file_uploads',  # 要先建好这个资料夹喔,在专案根目录
    'ALLOW_EXTENSIONS': ['txt', 'pdf', 'png', 'jpg']
}

app = Flask(__name__)
app.config.form_mapping(CONFIGS)


# 判断副档名是否允许上传
def is_allow_extensions(filename):
    return ('.' in filename) and (filename.split('.')[-1].lower() in app.config['ALLOW_EXTENSIONS'])


@app.route('/file-upload', methods=['POST'])
def file_upload():
    # 这边 request.files['<key name>'] 的 key name 等一下会用到
    f = request.files['files']
    filename = secure_filename(f.filename)
    if is_allow_extensions(filename):
        f.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
        return 'success'
    else:
        return 'error'

没错,这样就可以了,来开个 POSTMAN 测试看看吧(method 选 POST;输入参数选 Body -> form-data , 档案先放在 C:/Users/<user name>/Postman/files 里面;KEY 格式选 File,如果没看到File 的选项,滑鼠滑过去就会看到了;VALUE 选择档案後按 Send)!

如果出现 success ,就可以看一下是不是有正确上传了。

那麽就大概这样,接收传到後端的参数并不会很难,注意一下 KEY name 就可以了。

大家掰~掰~


<<:  [DAY21]Istio-手把手教安装

>>:  介绍Vertex(4) | ML#Day21

【21】不同的模型权重初始化 (Weight Initialization) 对应的使用方式

Colab连结 有关权重如何初始化也是个各派不同的训练方法,从 tf.keras 官方文档就看到一大...

Raspberry pi 与周边的沟通

Raspberry pi 提供的40根Pin中 有26个GPIO可用 当中有几个串列传输的技术是我们...

JAVA 语言

https://wolkesau.medium.com/java-语言-8e8158d75b5d J...

Day29 Gin with Async

前情提要 由於在POST /v1/users/ 时我们会需要透过smtp寄出通知信再回respons...

Day 26- 鬼斧神工 :Serverless 电商 - 实战 - 後端开发 (二)API 规划

前言 我们是要处理快速易用的网页,所以在,API方面要做到可以尽量少存取资料库来得到最大化资源使用。...