目录
- 一、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()
- 参数要写在<>中、
- 视图函数的参数要与路由中的一致
- 也可以指定参数类型(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()
前端运行结果:
- 路由中最后的"/"最好带上,否在访问时可能会报错。
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. 命令行控制启动
-
安装
pip install flask-script
-
使用
# 导入类库 from flask_script import Manager app = Flask(__name__) # 创建对象 manager = Manager(app) # 启动程序 if __name__ == '__main__': # app.run() # 命令行控制启动 manager.run()
-
参数:
启动:python manager.py runserver [-d] [-r] -? & --help 查看帮助 -d 开启调试模式 -r 修改文件自动加载 -h --host 指定主机 -p --port 指定端口 --threaded 使用多线程
-
详情参考: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. 使用函数
- 在要解析的变量的后面添加一个‘ | ’
- 在‘ | ’的后面添加一个需要处理的函数
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
-
网页显示如下:
-
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()
-
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>
-
网页内容显示如下:
6. 控制结构
-
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()
-
templates(存放模板文件夹)/control.html
- 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>
- 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.宏的使用
- 基础使用方法:(类似于自定义函数)
-
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()
-
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>
-
- 集中定义宏并在其他文件中调用:(将宏单独存放在一个文件中)
-
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()
-
文件一:设置宏
templates(存放模板文件夹)/macro2.html{# 这里是设置宏 #} {% macro welcome(name) %} <h1>This is {{name}}</h1> {% endmacro %}
-
文件二:调用宏
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.文件包含
-
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()
-
文件一:设置宏
templates/macro2.html{# 这里是设置宏 #} {% macro welcome(name) %} <h1>This is {{name}}</h1> {% endmacro %}
-
文件二:调用宏
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>
-
文件三:收录方法(类似拷贝文件)
templates/include.html{% include 'macro.html' %}
9.模板继承
- 首先,要有一个父类模板;
- 然后,需要让子类模板继承父类模板;
- 最后,写一个测试的路由,渲染子类模板。
-
文件一:创建父类模板
templates/parents.html{# 写一个块(block) #} <html> <head> {% block head %} <title> {% block title %} 默认标题 {% endblock %} </title> {% endblock %} </head> <body> {% block body %} 默认内容 {% endblock %} </body> </html>
-
文件二:创建子类模板
templates/children.html- 继承父类模板,并可以在继承基础上重写父类
- 继承父类模板,保留原有父级模板中的内容
{# 继承自parents模板 #} {% extends 'parents.html' %} {# 指定块,重写父类 #} {% block title %}首页{% endblock %} {% block head %} {# 保留原有父级模板中的内容 #} {{ super }} <h1>添加的内容</h1> {% endblock %} {# 删除基础模板中的指定块 #} {% block body%} {% endblock %}
extends
方法与include
方法有所不同,include
方法照搬过来的时候,不能进行重写等操作,而extends
方法可以做到。 -
文件三:写一个测试的路由,渲染子类模板
manager.pyfrom 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.使用
-
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()
-
templates/bootstrap.html
{# 继承自bootstrap的基础模板 #} {% extends 'bootstrap/base.html' %} {# 写标题 #} {% block title %}bootstrap测试{% endblock %} {# 写内容 #} {% block content %} <div class='container'> <h1>Hello {{name}} </h1> </div> {% endblock %}
-
bootstrap的基础模板中定义了很多block,可以在衍生模板中直接使用
块名 说明 doc 整个文档 html html标签中的内容 head head标签的内容 title title标签的内容 body body标签的内容 metas 一组metas标签 styles 层叠样式表 scripts 加载Js代码 content 自定义内容 navbar 定义导航条 说明:上述的block在子模板中都可直接使用,但是可能会出现覆盖问题,当出现问题时,很多时候都是因为没有调用super()
3.基础模板定制
- 继承bootstrap,自定义base模板
-
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 %}
-
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.自定义错误页面
-
添加视图函数
@app.errorhandler(404): def page_not_found(e): return render_template('404.html')
-
创建模板文件:404.html
{# 继承自bootstrap的基础模板 #} {% extends 'bootstrap.html' %} {% block title %}出错了!{% endblock %} {% block page_content %}大哥,你是不是搞错了@_@{% endblock %}
更多推荐
Flask之最易懂的基础教程一(2020年最新-从入门到精通)
发布评论