Flask框架基础入门,基本使用

258 阅读6分钟

@[TOC]

一、安装

1、下载

pip install flask

2、基本使用

from flask import Flask

# 用当前脚本名称实例化Flask对象,方便flask从该脚本文件中获取需要的内容
app = Flask(__name__)

# @app.route() 指定路由 ,methods指定方法
@app.route("/", methods=['GET'])
def index():
    return "Hello World!"

# 支持post请求
@app.route("/hi",methods=['POST'])
def hi():
    return "Hi World!"

# 启动一个本地开发服务器,激活该网页
app.run()


3、运行

# 1、直接执行py程序
py test,py

# 2、使用flask命令
flask --app test run
# debug模式
flask --app test run --debug
# 外部可访问
flask --app test run --host=0.0.0.0

二、基本语法

1、参数接收

(1)路径参数

from flask import Flask

app = Flask(__name__)

# 可以在路径内以/<参数名>的形式指定参数,默认接收到的参数类型是string

'''#######################
以下为框架自带的转换器,可以置于参数前将接收的参数转化为对应类型
string 接受任何不包含斜杠的文本
int 接受正整数
float 接受正浮点数
path 接受包含斜杠的文本
########################'''

# 访问http://localhost:5000/index/1 ;1就是id参数
@app.route("/index/<int:id>",)
def index(id):
    if id == 1:
        return 'first'
    elif id == 2:
        return 'second'
    elif id == 3:
        return 'thrid'
    else:
        return 'hello world!'

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

除了原有的转换器,我们也可以自定义转换器(pip install werkzeug):此处略了。

(2)form参数

接收post请求的form参数

# 判断请求方式
if request.method == 'POST':
	# 获取表单中name为username的文本域提交的数据
	name = request.form.get('username')
	# 获取表单中name为password的文本域提交的数据
	password = request.form.get('password')
	return name+" "+password

(3)Json处理

from flask import Flask
from flask import jsonify
from flask import request

app = Flask(__name__)
# 在Flask的config是一个存储了各项配置的字典
# 该操作是进行等效于ensure_ascii=False的配置
app.config['JSON_AS_ASCII'] = False

@app.route("/login", methods=['POST'])
def login():
   if request.method == 'POST':
      # 接收json数据,这个data就是json对象了
      data = request.get_json()
      username = data['username']
      password = data['password']
      print(username)
      print(password)
   
   # 将对象返回为json
   return jsonify({"login": "success"}) 

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

(4)get请求参数

from flask import Flask, request
 
app = Flask(__name__)
 
@app.route('/hello')
def hello():
    name = request.args.get('name')
    age = request.args.get('age')
    return f"Hello {name}, you are {age} years old!"
 
if __name__ == '__main__':
    app.run()

2、GET、POST请求

from flask import request
# 可以用methods指定,也可以直接使用@app.get
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        return do_the_login()
    else:
        return show_the_login_form()

@app.get('/login')
def login_get():
    return show_the_login_form()

@app.post('/login')
def login_post():
    return do_the_login()

3、拦截器

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello World!'

# before_request:在每一次请求之前调用 先绑定的先执行
@app.before_request
def before_request_a():
    print('I am in before_request_a')
 
@app.before_request
def before_request_b():
    print('I am in before_request_b')
 
# before_first_request:与before_request的区别是,只在第一次请求之前调用
@app.before_first_request
def teardown_request_a():
    print('I am in teardown_request_a')

@app.before_first_request
def teardown_request_b():
    print('I am in teardown_request_b')
 
# after_request:每一次请求之后都会调用 先绑定的后执行
@app.after_request
def after_request_a(response):
    print('I am in after_request_a')
    # 该装饰器接收response参数,运行完必须归还response,不然程序报错
    return response
 
@app.after_request
def after_request_b(response):
    print('I am in after_request_b')
    return response

# teardown_request:每一次请求之后都会调用 先绑定的后执行
# 代码替换视图函数hello_world后,if main前
@app.teardown_request
def teardown_request_a(exc):
    print('I am in teardown_request_a')
 
@app.teardown_request
def teardown_request_b(exc):
    print('I am in teardown_request_b')

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

4、上传文件

import os
from flask import Flask, flash, request, redirect, url_for
from werkzeug.utils import secure_filename

# 上传路径
#UPLOAD_FOLDER = '/path/to/the/
UPLOAD_FOLDER = 'E:\\testdir'
# 允许上传的文件类型
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'}

app = Flask(__name__)
# 文件上传路径
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
# 限制文件上传大小16 M
app.config['MAX_CONTENT_LENGTH'] = 16 * 1000 * 1000

# 判断文件格式是否允许上传
def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        # check if the post request has the file part
        if 'file' not in request.files:
            flash('No file part')
            return redirect(request.url)
        file = request.files['file']
        # If the user does not select a file, the browser submits an
        # empty file without a filename.
        if file.filename == '':
            flash('No selected file')
            return redirect(request.url)
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            # 文件保存到本地,上传完重定向的文件
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return redirect(url_for('download_file', name=filename))
    return '''
    <!doctype html>
    <title>Upload new File</title>
    <h1>Upload new File</h1>
    <form method=post enctype=multipart/form-data>
      <input type=file name=file>
      <input type=submit value=Upload>
    </form>
    '''

from flask import send_from_directory

@app.route('/uploads/<name>')
def download_file(name):
    return send_from_directory(app.config["UPLOAD_FOLDER"], name)
# 如果您正在使用中间件或者 HTTP 服务器为文件提供服务,那么可以把 download_file 端点注册为 build_only 规则,这样 url_for 会在 没有视图函数的情况下生效。
app.add_url_rule(
    "/uploads/<name>", endpoint="download_file", build_only=True
)
app.run()

5、使用html模板

Jinja2 模板引擎,可以参考:https://jinja.palletsprojects.com/en/3.1.x/templates/

from flask import render_template

from flask import Flask
app = Flask(__name__)
@app.route('/hello/')
@app.route('/hello/<name>')
def hello(name=None):
    return render_template('hello.html', name=name)

app.run()

模板文件需要在templates目录下。

<!doctype html>
<title>Hello from Flask</title>
{% if name %}
  <h1>Hello {{ name }}!</h1>
{% else %}
  <h1>Hello, World!</h1>
{% endif %}

三、高级用法

1、蓝图

引入蓝图(flask.Blueprint),用于实现程序功能的模块化

当接收到请求时,Flask会遍历Flask对象下(已注册)的各蓝图对象,比对蓝图对象中记录的url,比对成功则映射到该url绑定的视图函数并返回响应

# 模块一
from flask import Blueprint

# 实例化蓝图对象,参数一类似于蓝图对象的名称
# 一个app下的蓝图对象不可重名 可以指定前缀
product_list = Blueprint('products',__name__,url_prefix='/products')

# 蓝图对象的使用和app类似
# 一个蓝图下的视图函数名、endpoint不可重复

# http://localhost:5000/products/list
@product_list.route('/list')
def products():
    return '这是产品模块!'
# 模块二
from flask import Blueprint

# 实例化蓝图对象,参数一类似于蓝图对象的名称
# 一个app下的蓝图对象不可重名  可以指定前缀
new_list = Blueprint('news',__name__,url_prefix='/news')

# 蓝图对象的使用和app类似
# 一个蓝图下的视图函数名、endpoint不可重复

# http://localhost:5000/news/list
@new_list.route('/list')
def news():
    return '这是新闻模块!'
# 主方法
from flask import Flask

from sub import products,news

app = Flask(__name__)
@app.route('/')
def hello_world():
    return 'hello my world !'

# 将对应模块下的蓝图对象注册到app中
app.register_blueprint(news.new_list)
app.register_blueprint(products.product_list)

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

2、使用Gunicorn部署

注意,Gunicorn不支持windows,会报错No module named 'fcntl'

# 安装Gunicorn
pip install gunicorn

#  -w 指定线程数 -b绑定的ip
gunicorn -w 4 -b 0.0.0.0 hello:create_app()

参考资料

https://blog.csdn.net/wly55690/article/details/131683846

官方文档: https://www.osgeo.cn/flask/ https://dormousehole.readthedocs.io/en/latest/

【重磅推荐!免费简单内网穿透神器!支持linux+windows】

推荐内网穿透神器【cpolar】www.cpolar.com/ 点击【免费注册】之后,输入自己的个人信息就可以注册一个账号啦! 本地web项目如何使用外网访问?教你轻松使用cpolar在windows搭建内网穿透 linux虚拟机部署的web项目如何使用外网访问?教你轻松使用cpolar在centos搭建内网穿透 linux虚拟机部署的MySQL如何使用外网访问?教你轻松使用cpolar在centos搭建内网穿透