目录

      • 一、web工作原理
        • 1. B/S和C/S架构
        • 2. WEB工作原理
      • 二、Flask框架
        • 1. 简介
        • 2. 组成
        • 3. 安装
        • 4. 简单使用
        • 5. run方法参数
        • 6. 请求和响应
        • 7. 请求钩子装饰器
        • 8. 视图函数
          • 1. 不带参数的视图函数
          • 2. 带参数的视图函数
          • 3. 带类型限定(path)的视图函数
        • 9. 获取request请求值
        • 10. 响应的构造(make_response)
        • 11. 重定向(redirect)
        • 12. 终止abort
        • 13. 会话控制cookie和session(附加过期时间的设置)
          • 1. 会话控制cookie
          • 2. 会话控制session
        • 14. 命令行控制启动
        • 15.Flask模板
          • 1. 模板介绍:
          • 2. 模板引擎
          • 3. JinJa2(解析参数)
          • 4. 使用函数
          • 5. 常用函数
          • 6. 控制结构
          • 7.宏的使用
          • 8.文件包含
          • 9.模板继承
        • 16.使用bootstrap(基础模板引用)
          • 1.安装
          • 2.使用
          • 3.基础模板定制
          • 4.自定义错误页面

Flask框架的基础教程:

一、web工作原理

1. B/S和C/S架构

- B/S:浏览器/服务器架构(客户端需要更新才行)
- C/S:客户端/服务器架构(刷新页面即可更新)(可能会成为主流)

2. WEB工作原理

客户端 > 服务器 > python(flask) > 数据库(mysql)

二、Flask框架

1. 简介

  • 是一个非常小的框架,可以称为微型框架,只提供了一个强劲的核心,其他的功能都需要使用拓展来实现。意味着可以根据自己的需求量身打造;

2. 组成

  • 调试、路由、wsgi系统
  • 模板引擎(Jinja2)

3. 安装

  • pip install flask

4. 简单使用

  • 创建Flask框架。(社区版没有直接创建的功能,专业版有)
# 导入Flask类库
from flask import Flask
# 创建应用实例
app = Flask(__naem__)
# 视图函数(路由)
@app.route('/')
def index():
	return '<h1>Hello Flask!<h1>'
# 启动实施(只在当前模块运行)
if __name__ == '__main__':
	app.run()

5. run方法参数

参数说明默认值
debug代码更新是否自动重启False
theaded是否开启多线程False
port指定端口5000
host指定主机(设置0.0.0.0可以通过本地IP访问)127.0.0.1

6. 请求和响应

变量上下文描述
current_app应用上下文相当与在主程序中激活的实例化app(app=Flask(__name__)
g应用上下文一次性函数,处理请求的临时变量。只在一个请求中被应用,下个请求开始时会自动重置
request请求上下文请求对象。存放了客户端发来的HTTP信息
session请求上下文记录用户和服务器之间的会话的。在服务器端记录需要记住的信息。(和cookie对应,cookies是记录在客户端的)

7. 请求钩子装饰器

函数描述
before_first_request第一次请求之前
before_request每次请求之前
app.after_request没有异常,每次请求结束后
app.teardown_request有异常也会运行,每次请求结束后

说明:以上钩子函数若写在蓝图中,只能针对蓝本的请求。若想在蓝本中设置全局有效的函数,需要使用带app的钩子函数。如:before_first_request 变为 before_app_first_request。

8. 视图函数

1. 不带参数的视图函数
# 导入Flask类库
from flask import Flask
# 创建应用实例
app = Flask(__name__)
# 视图函数(路由)
@app.route('/index')
def index():
	return '<h1>Hello Flask!<h1>'
# 启动实施(只在当前模块运行)
if __name__ == '__main__':
	app.run()
2. 带参数的视图函数
# 导入Flask类库
from flask import Flask
# 创建应用实例
app = Flask(__name__)
# 视图函数(路由)
@app.route('/user/<username>')
def say_hello(username):
	return '<h1>Hello %s !<h1>' % username
# 启动实施(只在当前模块运行)
if __name__ == '__main__':
	app.run()
  1. 参数要写在<>中、
  2. 视图函数的参数要与路由中的一致
  3. 也可以指定参数类型(int/float/path),默认是字符串
3. 带类型限定(path)的视图函数
# 导入Flask类库
from flask import Flask
# 创建应用实例
app = Flask(__name__)
# 视图函数(路由)
@app.route('/user/<path:info>')
def test(info):
	return info
# 启动实施(只在当前模块运行)
if __name__ == '__main__':
	app.run()

前端运行结果:

  1. 路由中最后的"/"最好带上,否在访问时可能会报错。

9. 获取request请求值

# 导入Flask类库
from flask import Flask,request
# 创建应用实例
app = Flask(__name__)
# request
@app.route('/request/<path:info>')
def request_url(info):
	# 完整的请求URL
	return request.url
	'''
	url:127.0.0.1:5000/request/abc/def?username=xiaoming&pwd=123
	网页返回值:http://127.0.0.1:5000/request/abc/def?username=xiaoming&pwd=123
	'''
	# 去掉GET参数的URL
	return request.base_url
	'''
	网页返回值:http://127.0.0.1:5000/request/abc/def
	'''
	# 只有主机和端口的URL
	return request.host_url
	'''
	网页返回值:http://127.0.0.1:5000/
	'''
	# 装饰器中写的路由地址
	return request.path
	'''
	网页返回值:/request/abc/def
	'''
	# 请求方法类型
	return request.method
	'''
	网页返回值:GET (也有可能时POST)
	'''
	# 远程地址
	return request.remote_addr
	'''
	网页返回值:127.0.0.1:5000
	'''
	# 获取url参数
	return request.args.get('username')
	return request.args.get('pwd')
	return str(request.args)
	# 获取headers信息
	return request.headers.get('User-Agent')
# 启动实施(只在当前模块运行)
if __name__ == '__main__':
	app.run()

10. 响应的构造(make_response)

from flask import Flask,make_response
app = Flask(__name__)
@app.route('/response/')
def response():
	# 不指定状态码,默认为200,表示OK
	# return ‘OK’
	# 构造一个404状态码
	# 方法一
	return 'not fount',404
	# 方法二
	# 导入make_response
	# 自定义构造一个响应,然后返回200,构造也可以指定状态码404
	res = make_response('我是通过函数构造的响应',404)
	return res
if __name__ == '__main__':
	app.run()

11. 重定向(redirect)

from flask import Flask,redirect
app = Flask(__name__)
@app.route('/old/)
def old():
	# return '这里是原始内容。'
	# 如果输入旧的old路由,会指向新的地址。
	# 先输入一个外地请求试试
	return redirect('https://www.baidu')
	# 再输入一个本地请求试试
	return redirect('/new/')
	# 根据视图函数找到路由,指向方法:<url_for>中的参数'new'指向的是<函数名>
	return redirect(url_for('new'))
	return redirect(url_for('say_hello',username='xiaoming'))
@app.rout('/new/')
def new():
	return '这里是新的内容'
if __name__ == '__main__':
	app.run()

12. 终止abort

from flask import Flask
app = Flask(__name__)
@app.route('/login/')
def login():
	# return '欢迎登录'
	# 此处使用abort可以主动抛出异常
	abort(404)
if __name__ == '__main__':
	app.run()

13. 会话控制cookie和session(附加过期时间的设置)

1. 会话控制cookie
# 发送到response的headers里面(客户端)
from flask import Flask
import time
app = Flask(__name__)
@app.route('/set_cookie/')
def set_cookie():
	resp = make_response('设置cookie')
	# 指定过期时间
	expires = time.time + 10
	resp.set_cookie('name','xiaoming',expires=expires)
	return resp
if __name__ == '__main__':
	app.run()
# 发送到request的headers里面(服务器)
# 如果清除cookie后,会导致name=xiaoming的cookie被清除。
# 那么就会在网页显示'你是哪个?'
from flask import Flask,request
app = Flask(__name__)
@app.route('/get_cookie/')
def get_cookie():
	return request.cookie.get('name') or '你是哪个?'
if __name__ == '__main__':
	app.run()
2. 会话控制session
# 发送到response的headers里面(客户端)
from flask import Flask,session
import time,os
'''
这里可以给SECRET_KEY设置一个随机N位字符串:os.urandom(n)
'''
app = Flask(__name__)
# 设置一个随机18位字符串的密钥,也可以设置成固定字符串
app.config['SECRET_KEY'] = os.urandom(18)
# app.config['SECRET_KEY'] = '这是个密钥字符串'
@app.route('/set_session/')
def set_session():
	# session本身是个字典,需要直接添加键值对
	'''
	添加session值之前,必须先设置SECRET_KEY
	'''
	session['username'] = 'xiaoqiao'
	return 'session已设置'
@app.route('/get_session/')
def get_session():
	# 获取session中的username的值,否则返回'who are you ?'
	return session.get('username','who are you ?')
if __name__ == '__main__':
	app.run()

14. 命令行控制启动

  1. 安装
    pip install flask-script

  2. 使用

    # 导入类库
    from flask_script import Manager
    app = Flask(__name__)
    # 创建对象
    manager = Manager(app)
    # 启动程序
    if __name__ == '__main__':
    	# app.run()
    	# 命令行控制启动
    	manager.run()
    
  3. 参数:

    启动:python manager.py runserver [-d] [-r]
    -? & --help 查看帮助
    -d 			开启调试模式
    -r			修改文件自动加载
    -h --host	指定主机
    -p --port	指定端口
    --threaded	使用多线程	  
    
    
  4. 详情参考:https://blog.csdn/weixin_45950544/article/details/104047350

15.Flask模板

1. 模板介绍:
  • 结构清晰、易于维护的代码开发原则是程序员追求的目标之一。目前我们所写的代码都比较简单,但是很明显的可以预见的一个问题是,当项目越来越复杂时,视图函数将变得异常庞大和繁琐,因为视图函数中存放了业务逻辑和表现逻辑。
  • 解决这类问题的通用方法是将不同种类的逻辑分开存放:
    • 业务逻辑:存放在视图函数中,专门处理用户的业务需求;
    • 表现逻辑:存放在单独的模板文件夹中,负责表现效果。
2. 模板引擎
  • 指定了一套特定的语法来实现表达逻辑,提供了一种专门的替换接口将模板文件换成目标文件(html)。——flask中提供了专门的模板引擎(jinja2)
3. JinJa2(解析参数)
  • manager.py

    from flask import Flask,render_template,render_template_string,g
    from flask_script import Manager
    app = Flask(__name__)
    manager = Manager(app)
    @app.route('/index')
    def index():
    	# return '模板引擎测试'
    	# 渲染模板文件
    	return render_template('index.html')
    @app.route('/index')
    def welcome('/index/<name>'):
    	# 变量参数写在渲染函数的后面作为参数,前面的name是形参,后面的name是渲染模板中的解析内容
    	# return render_template('index.html',name=name)
    	# 第二种方法,使用render_template_string(渲染字符串)
    	# return render_template_string('<h2>hello {{ name }} ! <h2>',name=name)
    	# 第三种方法,使用  g(全局函数),不需要分配就可以在模板中使用,
    	# 只需要给定渲染模板即可;
    	g.name = name
    	return render_template('index.html')
    if __name__ == '__main__':
    	manager.run()
    
  • templates(存放模板文件夹)/index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>模板</title>
    </head>
    <body>
    	<h1>模板引擎测试</h1>	
    	{ # {{ }} 括号中的内容将被解析 # }
    	<h2> hello {{ name }} ! </h2>
    	<h3> hello {{ g.name }} ! </h3>
    </body>
    </html>
    
4. 使用函数
  1. 在要解析的变量的后面添加一个‘ | ’
  2. 在‘ | ’的后面添加一个需要处理的函数
5. 常用函数
函数说明
capitalize首字母大写
upper全部大写
lower全部小写
title每个单词首字母大写
trim去掉两边的空白
striptags去掉所有的HTML标签
safe即删除标签,又保留标签功能
  • manager.py

    from flask import Flask,render_template
    from flask_script import Manager
    app = Flask(__name__)
    manager = Manager(app)
    @app.route('/index')
    def welcome('/index/<name>'):
    	# 变量参数写在渲染函数的后面作为参数,
    	# 前面的name是形参,后面的name是渲染模板中的解析内容
    	return render_template('index.html',name=name)
    if __name__ == '__main__':
    	manager.run()
    
  • templates(存放模板文件夹)/index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>模板</title>
    </head>
    <body>
    	<h1>hello {{ name|capitalize }} ! </h1>	
    </body>
    </html>
    
  • 在网页上输入127.0.0.1:5000/index/xiaoming

  • 网页显示如下:

  1. manager.py

    from flask import Flask,render_template
    from flask_script import Manager
    app = Flask(__name__)
    manager = Manager(app)
    @app.route(/usefunc/)
    def ues_func():
    	return render_template('use_func.html',var='hanmeimei')
    	return render_template('use_func.html',var='<b>xiaoming</b>')
    if __name__ == '__main__':
    	manager.run()
    
  2. templates(存放模板文件夹)/use_func.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>模板</title>
    </head>
    <body>
    	<h1>hello {{ var|capitalize }} ! </h1>
    	{# 将有<b>xiaoming</b>的标签删除 #}
    	hello {{ var | striptags }} ! 
    	{# 即删除标签,又保留标签功能#}
    	hello {{ var | safe }} ! 
    </body>
    </html>
    
  3. 网页内容显示如下:

6. 控制结构
  1. manager.py

    from flask import Flask,render_template
    from flask_script import Manager
    app = Flask(__name__)
    manager = Manager(app)
    @app.route(/control/)
    def control():
    	# 分配了该怎么处理,没有分配该怎么处理
    	return render_template('control.html',name='xiaoming')
    if __name__ == '__main__':
    	manager.run()
    
  2. templates(存放模板文件夹)/control.html

    1. if…else 语句
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>模板</title>
    </head>
    <body>
    	{# 判断显示内容 #}
    	{# 如果分配了name的内容 #}
    	{% if name %}
    		<h1>hello {{ name|capitalize }} ! </h1>
    	{# 如果不分配 #}
    	{% else %}
    	<h1>请登录</h1>
    	{% endif %}
    </body>
    </html>
    
    1. for 语句
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>模板</title>
    </head>
    <body>
    	<ol>
    		{% for x in range(1,5) %}
    			{# 光显示 x 是不行的,因为没有进行解析。#}
    			{# 需要对 x 进行解析,用{{ }} #}	
    			<li> {{ x }} </li>
    		{% endfor %}
    	</ol>
    </body>
    </html>
    
7.宏的使用
  • 基础使用方法:(类似于自定义函数)
    1. manager.py

      from flask import Flask,render_template
      from flask_script import Manager
      app = Flask(__name__)
      manager = Manager(app)
      @app.route(/macro/)
      def macro():
      	return render_template('macro.html',name='xiaoming')
      if __name__ == '__main__':
      	manager.run()
      
    2. templates(存放模板文件夹)/macro.html

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>模板</title>
      </head>
      <body>
      	{# 这里是设置宏 #}
      	{% macro show(name) %}
      		<h1>This is {{name}}</h1>
      	{% endmacro %}
      	{# 下面是调用宏 #}
      	{{ show(name) }}
      </body>
      </html>
      
  • 集中定义宏并在其他文件中调用:(将宏单独存放在一个文件中)
    1. manager.py(不变)

      from flask import Flask,render_template
      from flask_script import Manager
      app = Flask(__name__)
      manager = Manager(app)
      @app.route(/macro/)
      def macro():
      	return render_template('macro.html',name='xiaoming')
      if __name__ == '__main__':
      	manager.run()
      
    2. 文件一:设置宏
      templates(存放模板文件夹)/macro2.html

      	{# 这里是设置宏 #}
      	{% macro welcome(name) %}
      		<h1>This is {{name}}</h1>
      	{% endmacro %}
      
    3. 文件二:调用宏
      templates(存放模板文件夹)/macro.html

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>模板</title>
      </head>
      <body>
      	{# 下面是调用宏 #}
      	{% from 'macro2.html' import welcome %}
      	{{ welcome(name) }}
      </body>
      </html>
      
8.文件包含
  1. manager.py

    from flask import Flask,render_template
    from flask_script import Manager
    app = Flask(__name__)
    manager = Manager(app)
    @app.route(/include/)
    def include():
    	return render_template('include.html',name='xiaowang')
    if __name__ == '__main__':
    	manager.run()
    
  2. 文件一:设置宏
    templates/macro2.html

    {# 这里是设置宏 #}
    {% macro welcome(name) %}
    	<h1>This is {{name}}</h1>
    {% endmacro %}
    
  3. 文件二:调用宏
    templates/macro.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>模板</title>
    </head>
    <body>
    	{# 下面是调用宏 #}
    	{% from 'macro2.html' import welcome %}
    	{{ welcome(name) }}
    </body>
    </html>
    
  4. 文件三:收录方法(类似拷贝文件)
    templates/include.html

    {% include 'macro.html' %}
    
9.模板继承
  • 首先,要有一个父类模板;
  • 然后,需要让子类模板继承父类模板;
  • 最后,写一个测试的路由,渲染子类模板。
  1. 文件一:创建父类模板
    templates/parents.html

    {# 写一个块(block) #}
    <html>
    <head>
    	{% block head %}
    	<title>
    		{% block title %}
    		默认标题
    		{% endblock %}
    	</title>
    	{% endblock %}
    </head>
    <body>
    	{% block body %}
    	默认内容
    	{% endblock %}
    </body>
    </html>
    
  2. 文件二:创建子类模板
    templates/children.html

    • 继承父类模板,并可以在继承基础上重写父类
    • 继承父类模板,保留原有父级模板中的内容
    {# 继承自parents模板 #}
    {% extends 'parents.html' %}
    {# 指定块,重写父类 #}
    {% block title %}首页{% endblock %}
    {% block head %}
    	{# 保留原有父级模板中的内容 #}
    	{{ super }}
    	<h1>添加的内容</h1>
    {% endblock %}
    {# 删除基础模板中的指定块 #}
    {% block body%}	{% endblock %}
    

    extends方法与include方法有所不同,include方法照搬过来的时候,不能进行重写等操作,而extends方法可以做到。

  3. 文件三:写一个测试的路由,渲染子类模板
    manager.py

    from flask import Flask,render_template
    from flask_script import Manager
    app = Flask(__name__)
    manager = Manager(app)
    @app.route(/extends/)
    def extends():
    	return render_template('children.html')
    if __name__ == '__main__':
    	manager.run()
    

16.使用bootstrap(基础模板引用)

1.安装

pip install bootstrap

2.使用
  1. bootstrap.py

    from flask_bootstrap import Bootstrap
    app = Flask(__name__)
    bootstrap= Bootstrap(app)
    @app.route(/bootstrap/)
    def bootstrap():
    	return render_template('bootstrap.html',name='xiaoming')
    if __name__ == '__main__':
    	manager.run()
    
  2. templates/bootstrap.html

    {# 继承自bootstrap的基础模板 #}
    {% extends 'bootstrap/base.html' %}
    
    {# 写标题 #}
    {% block title %}bootstrap测试{% endblock %}
    {# 写内容 #}
    {% block content %}
    <div class='container'>
    	<h1>Hello {{name}} </h1>
    </div>
    {% endblock %}
    
  3. bootstrap的基础模板中定义了很多block,可以在衍生模板中直接使用

    块名说明
    doc整个文档
    htmlhtml标签中的内容
    headhead标签的内容
    titletitle标签的内容
    bodybody标签的内容
    metas一组metas标签
    styles层叠样式表
    scripts加载Js代码
    content自定义内容
    navbar定义导航条

    说明:上述的block在子模板中都可直接使用,但是可能会出现覆盖问题,当出现问题时,很多时候都是因为没有调用super()

3.基础模板定制
  • 继承bootstrap,自定义base模板
  1. templates/base.html

    {# 继承自bootstrap的基础模板 #}
    {% from bootstrap/base.html %}
    {% block title %}博客{% endblock %}
    {% block navbar %}
    <nav class="navbar navbar-inverse" style='border-radius:0px;'>
       <div class="container">
           <!-- Brand and toggle get grouped for better mobile display -->
           <div class="navbar-header">
               <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                       data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                   <span class="sr-only">Toggle navigation</span>
                   <span class="icon-bar"></span>
                   <span class="icon-bar"></span>
                   <span class="icon-bar"></span>
               </button>
               <a class="navbar-brand" href="#">首页</a>
           </div>
    
            <!-- Collect the nav links, forms, and other content for toggling -->
            <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                <ul class="nav navbar-nav">
                    <li><a href="#">板块一</a></li>
                    <li><a href="#">板块二</a></li>
                </ul>
                <ul class="nav navbar-nav navbar-right">
                    <li><a href="#">登录</a></li>
                    <li><a href="#">注册</a></li>
                </ul>
            </div><!-- /.navbar-collapse -->
        </div><!-- /.container-fluid -->
    </nav>
    {% endblock %}
    
    {% block content %}
    <div class='container'>
    	{% block page_content %}
    	默认内容
    	{% endblock %}
    </div>
    {% endblock %}
    
  2. base.py

    from flask_bootstrap import Bootstrap
    app = Flask(__name__)
    bootstrap= Bootstrap(app)
    @app.route('/')
    def base():
    	return render_template('base.html')
    if __name__ == '__main__':
    	manager.run()
    

3.渲染效果:

4.自定义错误页面
  1. 添加视图函数

    @app.errorhandler(404):
    def page_not_found(e):
    	return render_template('404.html')
    
  2. 创建模板文件:404.html

    {# 继承自bootstrap的基础模板 #}
    {% extends 'bootstrap.html' %}
    {% block title %}出错了!{% endblock %}
    {% block page_content %}大哥,你是不是搞错了@_@{% endblock %}
    

更多推荐

Flask之最易懂的基础教程一(2020年最新-从入门到精通)