有测试问题请微信联系作者,备注来意(点击此处添加)
240
一名普通的测试打工人;专注自动化测试技术研究、实践、总结、分享、交流。
用我多年的经历,给大家带来更多实用的干货。
人若有志,就不会在半坡停止。

【Python Web开发】Flask框架使用

Web开发框架有哪些

Java的web开发框架有Spring Boot等,而Python的web开发框架则有‌Django‌、‌Flask‌等。
Django‌
这是一个高级的Python Web框架,以其强大的功能和简洁的接口而闻名。它鼓励快速开发和干净的设计,非常适合大型项目。Django采用MTV(Model、Template、View)模型组织资源,功能丰富,模板扩展选择多,但可能包含一些轻量级应用不需要的功能模块。
Flask‌
这是一个轻量级的Python Web框架,适合小型项目和快速原型开发。Flask的核心功能简单,但扩展性极强,可以通过插件和扩展来增加更多功能。它非常适合低流量或小型工程,但可能需要安装多种插件来支持大型工程。

Flask安装

pip install Flask
pip show flask查看安装信息

Flask框架创建项目

Pycharm→File→New Project

  1. 选择Flask
  2. 输入项目路径+项目名
  3. 选择解释器

运行项目

Flask基础使用

Flask框架目录结构

statictemplates目录是默认配置。
static用来存放静态资源,例如图片、js、css文件等。
templates存放模板文件。

Flask配置

Flask默认使用static目录存放静态资源,templates目录存放模板,这是可以通过设置参数更改的

app = Flask("my-app", static_folder="path1", template_folder="path2")    # "my-app"为该应用程序对象指定名称和根路径。

获取所有的url参数

from flask import Flask, request

app = Flask(__name__)


@app.route('/')
def hello_world():
    return request.args.__str__()


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

http://127.0.0.1:5000/?name=Flask&time&p=1&p=2

获取某个指定的参数

@app.route("/parm")
def get_parm():
    return request.args.get("name")

http://127.0.0.1:5000/parm?name=张三&age=18

参数获取None问题处理

request.args.get('info')返回Python内置的None,而Flask不允许返回None。

@app.route('/')
def hello_world():
    r = request.args.get('info')
    if r==None:
        # do something
        return ''
    return r

参数获取不到,设置默认值

request.args.get("name", "未获取到name参数,请检查")

参数多值处理

from flask import Flask, request

app = Flask(__name__)


@app.route('/')
def hello_world():
    r = request.args.getlist('p')  # 返回一个list
    return str(r)


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

获取POST方法传送的数据

from flask import Flask, request
app = Flask(__name__)

@app.route("/register", methods=["POST"])
def register():
    print(request.headers)          # 获取请求头
    print(request.stream.read())        # 获取请求数据
    return "post"

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

解析post请求的数据

request.form会自动解析数据。

@app.route("/register", methods=["POST"])
def register():
    print(request.headers)          # 获取请求头
    # print(request.stream.read())        # 获取请求数据(不能和request.form一起使用,否则下面的form取不到数据)
    print(request.form)
    print(request.form['password'])         # 键方式获取
    print(request.form.get('password'))
    print(request.form.get('name'))
    print(request.form.getlist('name'))     # 返回列表
    print(request.form.get('nickname', default='去不到,默认数据'))
    return "post"

请求接口

import requests

data = {"name1": "letian",
        "name": "张三",
        "password": "123"
        }
r = requests.post("http://127.0.0.1:5000/register", data)
print(r.text)

处理JSON格式的请求数据

如果POST的数据是JSON格式,request.json会自动将json数据转换成Python类型(字典或者列表)。

@app.route("/json", methods=["POST"])
def post_json():
    print(request.headers)
    print(type(request.json))
    print(request.json)  # 获取json请求数据
    result = request.json["a"] + request.json["b"]
    return str(result)

请求接口

import requests

json = {"a": 1, "b": 2}
r = requests.post("http://127.0.0.1:5000/json", json=json)
print(r.text)

# 返回 3

响应json---方案一

响应JSON时,除了要把响应体改成JSON格式响应头的Content-Type也要设置为application/json

import json
from flask import Flask, request, Response

@app.route('/response_json', methods=['POST'])
def response_json():
    result = {'sum': request.json['a'] + request.json['b']}
    return Response(json.dumps(result), mimetype='application/json')

请求接口

json = {"a": 1, "b": 2}
r = requests.post("http://127.0.0.1:5000/response_json", json=json)
print(r.headers)
print(r.text)

响应json---方案二

使用jsonify工具函数

@app.route('/jsonify', methods=['POST'])
def json_jsonify():
    result = {'sum': request.json['a'] + request.json['b']}
    return jsonify(result)

修改和新增响应头

@app.route('/response_json', methods=['POST'])
def response_json():
    result = {'sum': request.json['a'] + request.json['b']}
    resp = Response(json.dumps(result),  mimetype='application/json')   # 修改信息头
    resp.headers.add('Server', 'python flask')          # 添加信息头
    return resp


@app.route('/jsonify', methods=['POST'])
def json_jsonify():
    result = {'sum': request.json['a'] + request.json['b']}
    response = jsonify({'status': 'OK', 'message': result})
    response.headers['Content-Type'] = 'application/json; charset=utf-8'       # 修改信息头
    response.headers.add('Server', 'python flask')          # 添加信息头
    return response

上传文件

文件存放在,服务器端static/uploads目录下

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

# 文件上传
# 文件上传目录
app.config['UPLOAD_FOLDER'] = 'static/uploads/'
# 支持的文件格式
app.config['ALLOWED_EXTENSIONS'] = {'png', 'jpg', 'jpeg', 'gif'}  # 集合类型


# 判断文件名是否是我们支持的格式
def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1] in app.config['ALLOWED_EXTENSIONS']


@app.route('/upload', methods=['POST'])
def upload():
    upload_file = request.files['image']
    if upload_file and allowed_file(upload_file.filename):
        filename = secure_filename(upload_file.filename)
        # 将文件保存到 static/uploads 目录,文件名同上传时使用的文件名
        upload_file.save(os.path.join(app.root_path, app.config['UPLOAD_FOLDER'], filename))
        return 'info is ' + request.form.get('info', '') + '. success'
    else:
        return 'failed'

需要控制上产文件的大小,可以设置请求实体的大小

注意需要try:...except:...

try:
    app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024  # 16MB
except Exception as e:
    print(e)

获取文件内容

file_content = request.files['image'].stream.read()

URL参数化

Flask支持Restful URL的Web应用

@app.route('/user/<username>')    # 请求url,参数替代
def user(username):
    print(username)
    print(type(username))
    return 'hello ' + username


@app.route('/user/<username>/friends')
def user_friends(username):
    print(username)
    print(type(username))
    return 'hello ' + username

转换类型

数据类型转换

@app.route('/page/<int:num>')
def page(num):
    print(num)
    print(type(num))
    return 'hello world'

URL多参数

@app.route('/pages/<int:num1>-<int:num2>')
def pages(num1, num2):
    print(num1)
    print(num2)
    return 'hello world'

请求:http://127.0.0.1:5000/pages/11-44

使用url_for生成链接

工具函数url_for可以让你以软编码的形式生成url,提供开发效率。

from flask import Flask, url_for

app = Flask(__name__)

@app.route('/')
def hello_world():
    pass

@app.route('/user/<name>')
def user(name):
    pass

@app.route('/page/<int:num>')
def page(num):
    pass

# 软编码方式生成url
@app.route('/test')
def test():
    print(url_for('hello_world'))
    print(url_for('user', name='letian'))
    print(url_for('page', num=1, q='hadoop mapreduce 10%3'))
    print(url_for('static', filename='uploads/01.jpg'))
    return 'Hello'

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

redirect 重定向网址

redirect函数用于重定向,实现机制很简单,就是向客户端(浏览器)发送一个重定向的HTTP报文,浏览器会去访问报文中指定的url。

@app.route('/pages/<int:num1>-<int:num2>')
def pages(num1, num2):
    print(num1)
    print(num2)
    return 'hello world'

@app.route('/test')
def test():
    return redirect(url_for('pages', num1=4, num2=6, q='hadoop mapreduce 10%3'))


*浏览器会自动重定向

Jinja2 模板引擎

Jinja2模板引擎负责渲染html
模板引擎负责MVC中的V(view,视图)这一部分。
Flask默认使用Jinja2模板引擎。

Flask与模板相关的函数有:

  • flask.render_template(template_name_or_list, **context) ---常用
  • flask.render_template_string(source, **context) ---常用
  • flask.get_template_attribute(template_name, attribute)

创建并编辑/templates/default.html

<html>
<head>
    <title>
        {% if page_title %}
            {{ page_title }}
        {% endif %}
    </title>
</head>

<body>
    {% block body %}{% endblock %}
</body>
</html>

可以看到,在<head>标签中使用了if判断,如果给模板传递了page_title变量,显示之,否则,不显示。
<body>标签中定义了一个名为body的block,用来被其他模板文件继承。

创建并编辑/templates/user_info.html

{% extends "default.html" %}

{% block body %}
    {% for key in user_info %}

        {{ key }}: {{ user_info[key] }} <br/>

    {% endfor %}
{% endblock %}

变量user_info应该是一个字典,for循环用来循环输出键值对。

render_template使用

from flask import Flask, render_template

app = Flask(__name__)


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


@app.route('/user2')
def user2():
    user_info = {
        'name': 'letian',
        'email': '1234@aa.com',
        'age':0,
        'github': 'https://github.com/letiantian'
    }
    # render_template()函数的第一个参数指定模板文件,后面的参数是要传递的数据。
    return render_template('user_info.html', page_title='letian\'s info', user_info=user_info)  


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

浏览器访问http://127.0.0.1:5000/user2

查看网页源码

<html>
<head>
    <title>
            letian&#39;s info
    </title>
</head>
<body>
        name: letian <br/>
        email: 1234@aa.com <br/>
        age: 0 <br/>
        github: https://github.com/letiantian <br/>
</body>
</html>
posted @ 2024-12-19 15:51  三叔测试笔记  阅读(403)  评论(0)    收藏  举报
返回顶部 跳转底部