PythonWeb框架Flask学习(更新)

[toc]

写在前面

相信使用Python开发的朋友应该对flask这个轻量级web框架应该很熟悉了,我们这里就不做详细介绍了,本文主要介绍flask的安装,使用flask编写一个简单的web服务。

安装

我们知道Python主流的包管理工具是pip,首先你必须安装pip,这里我们使用的是Python3,pip的版本也是pip3,这里不做介绍了,怎么点击这里,或者直接使用以下命令:

pip install Flask

快速使用

简单实例

直接看实例:

from flask import Flask  #导入模块

app = Flask(__name__)  #启动配置

@app.route("/")  #装饰器,配置router
def hello():  #处理方法
    return "hello, world!"

接着使用命令:

$ export FLASK_APP=ppt1_2.py 
$ flask run 

或者我们这样使用:

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return "hello, world!"


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=3000) 

直接使用命令:

$ python3 ppt1_2.py 

配置

从配置中获取

from flask import Flask

app = Flask(__name__)
app.config["DEBUG"] = True  #配置
@app.route("/")
def hello():
    return "hello, world!"


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=3000)

启动服务我们可以看到日志中:

 * Serving Flask app 'ppt1_3'
 * Debug mode: on

从其他文件中获取

from flask import Flask

app = Flask(__name__)
app.config.from_object("config.base_setting")
@app.route("/")
def hello():
    return "hello, world!"


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=3000)

从环境变量中获取

from flask import Flask

app = Flask(__name__)
app.config.from_envvar("opt_config")
@app.route("/")
def hello():
    return "hello, world!"


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=3000)

从配置文件中获取

from flask import Flask

app = Flask(__name__)
app.config.from_file("config/base_setting.py")
@app.route("/")
def hello():
    return "hello, world!"


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=3000)

路由注册

flask路由注册主要有以下两种方式:

  • app.router()和app.add_url_rule()
  • 蓝图优化

app.route

实例:

from flask import Flask

app = Flask(__name__)


@app.route("/")  # 注册路由,绑定处理方法
def hello(): 
    return "hello, world!"


@app.route("/my_info")    # 注册路由,绑定处理方法
def my_info():
    return {"name": "iceymoss", "age": 18}


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=3000)

在url中传入参数:

from flask import Flask

app = Flask(__name__)


@app.route("/")
def hello():
    return "hello, world!"


@app.route("/my_info/<user_name>")
def my_info(user_name):
    return {"name": user_name, "age": 18}


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=3000)

访问:127.0.0.1:3000/my_info/idfjdif

返回:{“age”:18,”name”:”idfjdif”}

app.add_url_rule

实例:

from flask import Flask

app = Flask(__name__)


def hello():
    return "hello, world!"


def my_info(user_name):
    return {"name": user_name, "age": 18}


app.add_url_rule(rule="/", view_func=hello)
app.add_url_rule(rule="/my_info/<user_name>", view_func=my_info)

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=3000)

蓝图优化

实例:

from flask import Flask, Blueprint

app = Flask(__name__)

index_page = Blueprint("index_page", __name__)


@index_page.route("/")
def hello():
    return "hello, flask"


app.register_blueprint(index_page, url_perfix="/my_info")

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=3000)

使用蓝图我们可以进行分层,比如说我们的service负责编写处理方法,router目录负责配置路由注册绑定方法。

service:

from flask import Flask, Blueprint

index_page = Blueprint("index_page", __name__)


@index_page.route("/hello")
def hello():
    return "hello, flask"


@index_page.route("/user_info")
def get_user():
    return {"name":"iceymoss", "age": 18}

router:

from flask import Flask
from service import index_page

app = Flask(__name__)

app.register_blueprint(index_page, url_prefix="/api")

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=3000)

这样就完成了分层,结构更有层次。

方法

GET方法

实例:

@index_page.route("/add")
def get_good():
    var_a = request.args.get("a", 0) #request.args.get()获取get方法的参数
    var_b = request.args.get("b", 0)
    return "计算结果:{0}".format(int(var_b)+int(var_a))

访问:127.0.0.1:3000/api/add?a=10&b=1...

返回:计算结果:110

POST方法

实例:

@index_page.route("/login", methods=["POST"])
def loging():
    user_name = request.form["user_name"]
    password = request.form["password"]
    if user_name == "iceymoss" and password == "admin123":
        return {"code": 0, "msg": "", "token": "difhdanf3rudifndf.dfrhindfidf89er.49fhdigjaihg8qa"}

    return "用户名称或密码不正确"

浏览器不能直接测试post方法,这里使用apifox进行测试:

PythonWeb框架Flask学习

文件上传

实例:

@index_page.route("upload", methods = ["POST"])
def upload():
    f = request.files["file"] if "file" in request.files else None
    return "request: %s, params: %s, file:%s"%(request.method, request.files, f)

响应

简单的阅读完请求的内容,现在我们看一下在处理方法内部如果做响应,首先我们需要导入flask的make_response模块,然后使用make_response提供的方法让我们可以根据业务需求完成对应的响应。

普通响应

实例:

from flask import Flask, Blueprint, request, make_response

index_page = Blueprint("index_page", __name__)

@index_page.route("/text_same")
def text_same():
    response = make_response("text/html", 200) # 设置响应
    return response

json响应

返回json数据类型

实例:

from flask import Flask, Blueprint, request, make_response

index_page = Blueprint("index_page", __name__)

@index_page.route("/json")
def json():
    import json
    user_info = {"name": "iceymoss", "age": 18, "live": "ShangHai"} # 返回数据
    response = make_response(json.dumps(user_info)) # 转json
    response.headers["Content-Type"] = "application/json"  # 配置响应头信息
    return response

一种更简洁的方式完成以上功能:

实例:

from flask import Flask, Blueprint, request, make_response, jsonify

@index_page.route("/json_test")
def json_test():
    user_info = {"name": "iceymoss", "age": "18", "live": "ShangHai"}
    response = make_response(jsonify(user_info))
    return response

渲染模版

首先我们要知道目录层级:

├── router.py
├── service.py
└── templates
    └── index.html

index.html:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
        <meta name="Description", content="首页">
        <meta name="Keywords", content="责任、关爱">

    </head>
    <body>
        <div class="header">

            <!-- 网页logo -->
            <div class="loge">
                <h1>欢迎来到首页!</h1>
            </div>
        </div>
    </body>
</html>

router.py:

from flask import Flask
from service import index_page

app = Flask(__name__)

app.register_blueprint(index_page, url_prefix="/api")

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=3000)

service.py:

from flask import Flask, Blueprint, request, make_response, jsonify, render_template

index_page = Blueprint("index_page", __name__)

@index_page.route("/index")
def index():
    return render_template("index.html") 

注意:默认会到和程序入口的同级目录找templates目录,然后匹配对应的index.html

jinja2

传递变量

我们将python程序中的变量写入到thml中,这里目录结构和上一个实例一致。

实例:

from flask import Flask, Blueprint, render_template

index_page = Blueprint("index_page", __name__)


@index_page.route("/index")
def index():
      # 传值
    name = "iceymoss"
    return render_template("index.html", name=name)

访问:127.0.0.1:3000/api/index

返回:

欢迎来到首页!
iceymoss

我们也可以直接使用字典,实例:

from flask import Flask, Blueprint, render_template

index_page = Blueprint("index_page", __name__)


@index_page.route("/index")
def index():
    user_info = {"name": "iceymoss", "age": "18", "live": "ShangHai"}
    return render_template("index.html", name=user_info)

返回:

欢迎来到首页!
{'name': 'iceymoss', 'age': '18', 'live': 'ShangHai'}

jinja2语法

if和for

我们在html中经常会使用到if和for,现在我们看一看jinja2是如何实现的

实例:

from flask import Flask, Blueprint, render_template

index_page = Blueprint("index_page", __name__)


@index_page.route("/index")
def index():
    user_info = {"name": "蔡徐坤", "age": "28", "live": "ShangHai", "Skill": ["唱", "跳", "rap", "篮球"], "Features":["ban小黑子", "你干嘛!哎呦", "🐔霓太美"]}
    return render_template("index.html", user=user_info)

下面是html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
        <meta name="Description", content="首先">
        <meta name="Keywords", content="责任、关爱">

    </head>
    <body>
        <div class="header">

            <!-- 网页logo -->
            <div class="loge">
                <h1>欢迎来到首页!
                    <p>
                        {% if user %}
                        姓名:{{user.name}} 年龄:{{user.age}} 现居:{{user.live}}
                        {% endif %}}
                    </p>
                    <p>
                        {% for Skill in user.Skill %}
                        {{Skill}}
                        {% endfor %}
                    </p>
                     <p>
                        {% for Feature in user.Features %}
                        {{Feature}}
                        {% endfor %}
                    </p>
                </h1>
            </div>
        </div>
    </body>
</html>

这样我们访问:127.0.0.1:3000/api/index

返回:

欢迎来到首页!
姓名:蔡徐坤 年龄:28 现居:ShangHai }

唱 跳 rap 篮球

ban小黑子 你干嘛呢哎呦 🐔霓太美
模版继承

判断Jinja 中最强大的部分就是模板继承。模板继承允许你构建一个包含你站点共同元素的基 本模板“骨架〞,并定义子模板可以覆盖的 块。听起来复杂,实际上很简单,实例结构:

├── router.py
├── service.py
└── templates
    ├── common
    │   └── layout.html
    ├── extend_template.html

router.py:

from flask import Flask
from service import index_page

app = Flask(__name__)

app.register_blueprint(index_page, url_prefix="/api")

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=3000)

service.py:

from flask import Flask, Blueprint, render_template

index_page = Blueprint("index_page", __name__)


@index_page.route("/index")
def index():
    user_info = {"name": "蔡徐坤", "age": "28", "live": "ShangHai", "Skill": ["唱", "跳", "rap", "篮球"], "Features":["ban小黑子", "你干嘛呢哎呦", "🐔霓太美"]}
    return render_template("index.html", user=user_info)

@index_page.route("/extend_template")
def extend():
    return render_template("extend_template.html")

extend_template.html:

{% extends "common/layout.html" %}

{% block content %}
练习时长两年半
{% endblock %}

layout.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>统一模版</title>
</head>
<body>
  {% block content %} {% endblock %} <!--插入区域-->
</body>
</html>

访问:127.0.0.1:3000/api/extend_template

返回:练习时长两年半

本作品采用《CC 协议》,转载必须注明作者和本文链接
刻意学习
讨论数量: 6

前段时间也在学习flask,用过php的框架感觉flask有点原始啊

6个月前 评论
ice_moss (楼主) 6个月前

我在试着用laravel的方式封装 flask

6个月前 评论
ice_moss (楼主) 6个月前

感觉 fastapi 要好点,就是生态不行

6个月前 评论
ice_moss (楼主) 6个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
未填写
文章
118
粉丝
89
喜欢
173
收藏
246
排名:365
访问:2.6 万
私信
所有博文
社区赞助商