Flask介绍

原文地址:http://www.cnblogs.com/wupeiqi/articles/5341480.html

Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架.

Werkzeug本质就是Socket服务端,其用于接收http请求并对请求进行预处理,然后触发Flask框架,开发人员基于Flask框架提供的功能对请求进行相应的处理,并返回给用户,如果返回给用户的内容很复杂,就需要借助jinja2模板引擎来实现对模板的处理,即:将模板和数据进行渲染,将渲染后的字符串数据返回给用户浏览器。

“微”(micro) 并不表示你需要把整个 Web 应用塞进单个 Python 文件(虽然确实可以 ),也不意味着 Flask 在功能上有所欠缺。微框架中的“微”意味着 Flask 旨在保持核心简单而易于扩展。Flask 不会替你做出太多决策——比如使用何种数据库。而那些 Flask 所选择的——比如使用何种模板引擎——则很容易替换。除此之外的一切都由可由你掌握。如此,Flask 可以与您珠联璧合。

默认情况下,Flask 不包含数据库抽象层、表单验证,或是其它任何已有多种库可以胜任的功能。然而,Flask 支持用扩展来给应用添加这些功能,如同 Flask 本身实现的一样。众多的扩展提供了数据库集成、表单验证、上传处理、各种各样的开放认证技术等功能。Flask 也许是“微小”的,但它已经准备好在需求繁杂的生产环境中投入使用。

另外的介绍:

Flask诞生于2010年,是Armin ronacher(人名)用 Python 语言基于 Werkzeug 工具箱编写的轻量级Web开发框架。

Flask 本身相当于一个内核,其他几乎所有的功能都要用到扩展(邮件扩展Flask-Mail,用户认证Flask-Login,数据库Flask-SQLAlchemy),都需要用第三方的扩展来实现。比如可以用 Flask 扩展加入ORM、窗体验证工具,文件上传、身份验证等。Flask 没有默认使用的数据库,你可以选择 MySQL,也可以用 NoSQL。

其 WSGI 工具箱采用 Werkzeug(路由模块),模板引擎则使用 Jinja2。这两个也是 Flask 框架的核心。

Flask常用扩展包:

  • Flask-SQLalchemy:操作数据库;
  • Flask-script:插入脚本;
  • Flask-migrate:管理迁移数据库;
  • Flask-Session:Session存储方式指定;
  • Flask-WTF:表单;
  • Flask-Mail:邮件;
  • Flask-Bable:提供国际化和本地化支持,翻译;
  • Flask-Login:认证用户状态;
  • Flask-OpenID:认证;
  • Flask-RESTful:开发REST API的工具;
  • Flask-Bootstrap:集成前端Twitter Bootstrap框架;
  • Flask-Moment:本地化日期和时间;
  • Flask-Admin:简单而可扩展的管理接口的框架

安装:pip install flask

简单示例:

 1 from flask import Flask
 2 
 3 # 创建一个flask的应用程序,名字叫app
 4 # flask对象的名字 = Flask(__name__)
 5 # app可以随意起名字
 6 # __name__:表示模块名
 7 
 8 app = Flask(__name__)
 9 
10 """
11 通过装饰器,设置请求的路由
12 路由:就是一个url的地址,或者在java中也叫做接口
13 语法:@flask对象的名字.route("路径")
14 注意:app是对象的名字,名字可以随意取
15 @app.route('/aaa'):参数必须以/开头,否则会报错  ValueError: urls must start with a leading slash
16 def index():def表示定义一个函数,index是函数名字 函数名字随意取
17 """
18 @app.route('/')
19 def index():
20     """写我们的业务逻辑"""
21     # return表示展示页面,渲染页面,渲染就是展示的意思
22     return "我是第一个flask应用程序"
23 
24 
25 # 判断是否是入口
26 # 表示入口函数,固定语法
27 if __name__ == '__main__':
28     # 启动应用程序
29     app.run()

初始化参数介绍:

 1 from flask import Flask
 2 
 3 """
 4 查看参数的快捷键:ctrl + p
 5 static_path='xxx':静态路径,为了向下兼容,有些低版本使用的是这个
 6 static_url_path='xxx':url路径.表示的也是静态路径,
 7 表示的是一个意思,目的是为了向下兼容,表示静态文件
 8 static_folder='static',表示静态文件夹,系统默认叫static,里面存放静态文件,比如图片等等
 9 template_folder='teplates':模板文件夹,里面存放HTML文件
10 """
11 app = Flask(__name__, static_path=None, static_url_path=None, static_folder='static',template_folder='templates')
12 
13 
14 @app.route("/")  # 千万注意:是/    不是.是斜杠/
15 def index():
16     return "index page"
17 
18 
19 if __name__ == '__main__':
20     app.run()
21 """
22 lsof -i 5000:监听5000端口
23 kill -9 4728: 杀死5000端口的应用PID
24 
25 PID是进程id
26 
27 加载方式:
28 from_object   对象
29 from_pyfile   文件
30 from_envvar   环境变量
31 """
View Code

 对象方式加载配置文件:

 1 """
 2 起名字不要用中文
 3 """
 4 from flask import Flask
 5 
 6 app = Flask(__name__)
 7 
 8 
 9 class Config(object):
10     """创建一个配置类,名字叫Config,名字随便取"""
11     # 开启调试模式,调试模式为True
12     # 自下而上找错误
13     # 加载配置文件的好处:可以看到具体的错误信息,自动定位到错误的位置
14     DEBUG = True
15     # 自定义参数,参数不可以小写.只能是大写
16     # 大小写切换快捷键:ctrl + shift +u
17     ITCAST = "python"
18 
19 
20 # flask程序 从对象加载配置文件,配置文件来自Config这个对象
21 app.config.from_object(Config)
22 
23 
24 @app.route("/")
25 def index():
26     # a = 1 / 0
27     # 如果是自定义的参数,就需要自己取
28     # 如果从对象中取自定义的值,必须从对象读取,不能从文件读取
29     print(app.config.get('ITCAST'))
30     return 'index page'
31 
32 
33 if __name__ == '__main__':
34     app.run()
View Code

文件方式加载配置文件:

注意:先要在同级目录下创建一个config.cfg文件

 1 from flask import Flask
 2 
 3 app = Flask(__name__)
 4 
 5 
 6 class Config(object):
 7     """创建一个配置类,名字叫Config,名字随便取"""
 8     # 开启调试模式,调试模式为True
 9     # 自下而上找错误
10     # 加载配置文件的好处:可以看到具体的错误信息,自动定位
11     DEBUG = True
12 
13 
14 # flask程序 从文件加载配置文件
15 # 从对象加载必须 掌握,文件加载也得会
16 # 从对象加载的参数里面传入的是对象
17 # 从文件加载的参数里面传入的是文件名,是字符串类型,有引号
18 app.config.from_pyfile("config.cfg")
19 
20 
21 @app.route("/")
22 def index():
23     a = 1 / 0
24     return 'index page'
25 
26 
27 if __name__ == '__main__':
28     app.run()
View Code

run()参数:

 1 from flask import Flask
 2 
 3 app = Flask(__name__)
 4 
 5 
 6 @app.route('/')
 7 def index():
 8     a = 1/0
 9     return 'index page'
10 
11 
12 if __name__ == '__main__':
13     """
14     修改ip地址:
15     第一个参数是ip地址,
16     第二个是端口号,
17     第三个是开启调试模式(和之前的DEBUG是一样的功能,
18     这里是系统为了方便写在这里的.开发的时候需要自己写)
19     
20     一般不建议修改,就使用这个默认的值就好
21     """
22     app.run(host='192.168.14.27', port=9000, debug=True)
View Code

开启debug=True模式后,详细的报错信息就会展示在控制台.

 路由系统:

  • @app.route('/user/<username>')
  • @app.route('/post/<int:post_id>')
  • @app.route('/post/<float:post_id>')
  • @app.route('/post/<path:path>')
  • @app.route('/login', methods=['GET', 'POST'])

常用路由系统有以上五种,所有的路由系统都是基于下面的对应关系来处理:

 1 #: the default converter mapping for the map.
 2 DEFAULT_CONVERTERS = {
 3     'default':          UnicodeConverter,
 4     'string':           UnicodeConverter,
 5     'any':              AnyConverter,
 6     'path':             PathConverter,
 7     'int':              IntegerConverter,
 8     'float':            FloatConverter,
 9     'uuid':             UUIDConverter,
10 }

自定义转换器进行正则匹配:

 1 """
 2 之前只是限制数据类型,今天限制更多了.
 3 限制位数,每一位的数据类型等
 4 """
 5 from flask import Flask
 6 
 7 # routing 和路由相关的都在这里  第一步:
 8 from werkzeug.routing import BaseConverter
 9 """
10 转换器:converter
11 """
12 
13 app = Flask(__name__)
14 
15 
16 # 需要自定义转换器,通过正则方式进行自定义转换器,
17 # alt+enter快捷键就是进行导包  第二步:继承
18 class RegBaseConverter(BaseConverter):
19     # 表示限制的数据类型是数字,并且只能是5位,regex不能随便取,只能是regex,父类中定义好了
20     regex = 'd{5}'
21 
22 
23 # app.url_map得到所有的url地址(也就是路由)
24 # converters 表示转换器
25 # 自定义转换器,那么需要给自定义转换器起一个名字.注意:自己取的名字不能和系统的重名
26 # 把我们自定义的转换器放到converters这个转换器的集合里面  第三步:添加到转换器字典中
27 app.url_map.converters['aaaaaa'] = RegBaseConverter
28 
29 
30 # 限制数据类型是整型,只能限制数据类型.不能限制参数的位数.不好用.
31 # <aaaaaa:index_id>:进行替换,aaaaaa在这里就代表上面的正则表达式  第四步:使用
32 @app.route('/index/<aaaaaa:index_id>')
33 def index(index_id):
34     return 'index=%s' % index_id
35 
36 
37 if __name__ == '__main__':
38     app.run()
39 """
40 DEFAULT_CONVERTERS = {
41     'default':          UnicodeConverter,
42     'string':           UnicodeConverter,
43     'any':              AnyConverter,
44     'path':             PathConverter,
45     'int':              IntegerConverter,
46     'float':            FloatConverter,
47     'uuid':             UUIDConverter,
48 }
49 
50 一共6种转换器,前面两种是一样的.默认的是接收所有的和字符型一样
51 """
View Code

更专业的解答:https://segmentfault.com/q/1010000000125259

模板:

1、模板的使用

Flask使用的是Jinja2模板,所以其语法和Django无差别

2、自定义模板方法

Flask中自定义模板方法的方式和Bottle相似,创建一个函数并通过参数的形式传入render_template,如:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>模板</title>
 6 </head>
 7 <body>
 8 <h1>获取到后台传来的数据:</h1>
 9 {#    {{ 变量名 }} 表示模板文件的语法,用来获取后端传来的变量   #}
10 {#    变量.键 的方式获取键对应的值 只要是字典格式的数据,获取key对应的value
11 都是采用对象/变量 .key的方式
12 #}
13 {#使用p标签之后,输出显示就是一行一行的显示#}
14 <p>名字:{{ data_obj.name }}</p>
15 <p>年龄{{ data_obj.age }}</p>
16 <p>地址:{{ data_obj.address }}</p>
17 <p>列表数据:{{ data_obj.my_list }}</p>
18 <p>字典中的城市数据:{{ data_obj.my_dict.city }}</p>
19 </body>
20 </html>

对应的后台.py文件:

 1 from flask import Flask, render_template
 2 
 3 app = Flask(__name__)
 4 
 5 """
 6 模板传递数据:
 7 注意:
 8 模板其实是一个包含响应文本的文件.
 9 本质就是一个响应的文件.记住:是文件,文件
10 误区:模板就是HTML.  
11 
12 作用:
13 1.降低耦合度,更好的控制代码
14 """
15 
16 
17 @app.route('/login')
18 def index():
19     # 业务逻辑已实现
20     # 处理用户名,密码
21     data = {
22         'name': 'libin',
23         'age': 56,
24         'address': 'USA',
25         'my_list': [1, 2, '45'],
26         'my_dict': {'city': 'sz'}
27     }
28     # 第一个参数是模板文件的名字,
29     # 第二个参数是需要传递到文件上面的数据,前面参数是占位符,后面的是变量的名字
30     return render_template('demo1.html', data_obj=data)
31 
32 
33 if __name__ == '__main__':
34     app.run()
View Code

公共组件:

1、请求

对于Http请求,Flask会讲请求信息封装在request中(werkzeug.wrappers.BaseRequest),提供的如下常用方法和字段以供使用:

 1 request.method
 2 request.args
 3 request.form
 4 request.values
 5 request.files
 6 request.cookies
 7 request.headers
 8 request.path
 9 request.full_path
10 request.script_root
11 request.url
12 request.base_url
13 request.url_root
14 request.host_url
15 request.host

常用的介绍:

args参数:

 1 # ------------------------------args参数-------------------
 2 """
 3 args:就是get请求时url后面加?的后面的数据
 4 """
 5 from flask import Flask, request
 6 
 7 app = Flask(__name__)
 8 
 9 
10 @app.route('/index', methods=['GET', 'POST'])
11 def index():
12     # ?号后面的数据
13     # request.args :获取到?后面的数据
14     city = request.args.get('city')
15     print(city)
16     return 'index'
17 
18 
19 if __name__ == '__main__':
20     app.run()

form表单数据:

 1 """
 2 request获取数据
 3 """
 4 # -------------------form表单-------------------------
 5 from flask import Flask, request
 6 
 7 app = Flask(__name__)
 8 
 9 
10 @app.route('/index', methods=['GET', 'POST'])
11 def index():
12     print('前端请求的url地址:', request.url)
13     """所有的请求数据都是封装在request里面"""
14     # request.form:获取到表单数据
15     # request.form.get():获取到表单里面具体的某一个数据
16     name = request.form.get('name')
17     pwd = request.form.get('pwd')
18     return 'name=%s,pwd=%s' % (name, pwd)
19 
20 
21 if __name__ == '__main__':
22     app.run()

files多媒体数据:

 1 # -----------------------files多媒体-------------------
 2 from flask import Flask, request
 3 
 4 app = Flask(__name__)
 5 
 6 
 7 # 上传图片,只能选POST方式
 8 @app.route('/', methods=['POST'])
 9 def index():
10     # request.files 获取多媒体数据,比如拿到图片
11     pic = request.files.get('pic')
12     # pic.save('./bb.png') :保存图片,上传图片
13     pic.save('./bb.png')
14     return '上传成功!'
15 
16 
17 if __name__ == '__main__':
18     app.run()

返回JSON格式数据:

from flask import Flask, jsonify

app = Flask(__name__)


# -------------------就是返回给客户端呈现的数据是json格式的-----------
@app.route('/')
def index():
    data = {
        "name": "python",
        "age": 29
    }
    # -------------jsonify方式-------------------------------------------
    return jsonify(data)


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

原生方式返回JSON:

# ------------------------原生方式:json.dumps()----------------------------
from flask import Flask
import json

app = Flask(__name__)


@app.route('/')
def index():
    data = {
        "name": "python",
        "age": 29
    }

    # -------------原生方式json.dumps()--------
    # 直接返回报错,需要进行包装一下,告诉系统这是个json数据.python默认会识别为字典
    # json.dumps()字典数据转成json数据
    res = json.dumps(data)
    # 第一个参数表示内容,第二个参数表示状态码,第三个表示数据类型
    return res, 200, {'Content-Type': 'application/json'}


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

重定向:

 1 """
 2 重定向:请求页面的时候,请求页面不存在,返回的是另外一个页面.
 3 一般在双11的活动的时候,活动页面...
 4 京东原来的域名www.360.buy.com,如果访问原来的就需要跳转到现在的域名www.jd.com
 5 
 6 """
 7 from flask import Flask, redirect, url_for  #  redirect, url_for 这两个是重定向模块
 8 
 9 app = Flask(__name__)
10 
11 
12 @app.route('/360buy')
13 def index():
14     # redirect 重定向
15     """
16 17    url_for会根据传入的路由函数名,返回该路由对应的URL,在模板中始终使用url_for()就可以安全的修改路由绑定的URL,则不必担心模板中渲染url链接出错:
18    19     """
20     return redirect(url_for('jd'))
21 
22 
23 @app.route('/jd')
24 def jd():
25     return '进入到京东商城页面'
26 
27 
28 if __name__ == '__main__':
29     app.run()

自定义状态码:

 1 from flask import Flask
 2 
 3 app = Flask(__name__)
 4 
 5 """
 6 自定义状态码:
 7 使用场景:
 8     错误代码的对照表.可以自己定义相关的错误.比如实际开发中的具体错误:10004表示注册成功后未登录等等
 9 
10 在交互成功之后要求交互成功的内容再具体一点,是交互的哪些内容成功?
11 """
12 
13 
14 @app.route('/')
15 def index():
16     # 999 是请求状态码,是自定义的状态码
17     return 'index', 999  # 返回客户端给用户看的,999表示...错误
18 
19 
20 if __name__ == '__main__':
21     app.run()

abort异常捕获:

 1 """
 2 abort的作用:
 3 1.捕获HTTP的异常(之前是try...exception抓取),这里flask重新进行了封装.
 4 2.终止程序
 5 3.抛出异常
 6 
 7 细节-注意:在abort(500)函数中和@app.errorhandler(500)中,
 8 参数必须是http协议标准的状态码.
 9 
10 abort(状态码)和@app.errorhandler(状态码)中的参数都是状态码,这两个状态码必须一致.即这两个参数必须一致.
11 
12 abort(参数1)和@app.errorhandler(参数2):注意,参数1和参数2必须一致
13 
14 
15 在开发中实际应用:
16 1.一般用来展示404的页面(资源没找到,请求页面不存在)
17 
18 19 """
20 from flask import Flask, abort
21 
22 app = Flask(__name__)
23 
24 
25 @app.route('/')
26 def index():
27     name = ''
28     pwd = ''
29 
30     if name != 'admin' and pwd != '123':
31         print('进入了函数')
32         # 把程序终止掉,后面的业务逻辑就不需要执行了,因为即使执行也没有实际意义
33         abort(500)
34         # 进入到数据库,进行数据库查询
35         print('看看我进入数据库了没')
36     return 'index page'
37 
38 
39 @app.errorhandler(500)  # 抛出捕获到的异常信息
40 def error_500_handler(error):
41     # return '程序报错了:%s' % error
42     return '替换为一个html页面'
43 
44 
45 if __name__ == '__main__':
46     app.run()

内置过滤器filter:

 1 from flask import Flask, render_template
 2 
 3 app = Flask(__name__)
 4 
 5 """
 6 过滤器本质就是一个函数.
 7 作用:
 8 1.不仅仅只是输出值
 9 2.还希望更改值
10 
11 """
12 
13 
14 @app.route('/')
15 def index():
16     return render_template('demo2.html')
17 
18 
19 if __name__ == '__main__':
20     app.run()

对应的HTML:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>过滤器</title>
 6 </head>
 7 <body>
 8 <h1>过滤器的使用</h1>
 9 {#{{ 需要修改的值|过滤器的名字 }}#}
10 {# capitalize: 首字母大写#}
11 <p>首字母大写:{{ 'hello'|capitalize }}</p>
12 {# 模板中处于安全考虑,默认情况下,会把标签进行转义,即把<>这个转成 &lt;&gt; #}
13 {# 但是在 开发中,我们有时候需要使用标签展示 ,需要禁止转义 #}
14 <p>禁止转义:{{ '<h1>黑马程序员</h1>'|safe }}</p>
15 <p>单词大写:{{ 'hello'|upper }}</p>
16 <p>单词小写:{{ 'HELLO'|lower }}</p>
17 <p>单词反转:{{ 'hello'|reverse }}</p>
18 <p>每个单词的首字母大写:{{ 'hello world!'|title }}</p>
19 <hr>
20 
21 <h1>列表操作:</h1>
22 <p>获取列表中的第一个元素:{{ [1,2,3,4,5,6]|first }}</p>
23 <p>获取列表中的最后一个元素:{{ [1,2,3,4,5,6]|last }}</p>
24 <p>列表求和:{{ [1,2,3,4,5,6]|sum }}</p>
25 <p>列表排序:{{ [11,21,3,4,5,6]|sort }}</p>
26 <hr>
27 
28 
29 
30 </body>
31 </html>

自定义过滤器:

 1 from flask import Flask, render_template
 2 
 3 app = Flask(__name__)
 4 
 5 """
 6 过滤器本质就是一个函数.
 7 内置的无法满足需求
 8 自定义过滤器实际上就是写自定义函数
 9 
10 app.add_template_filter(do_setup2, 'xx'):
11 1.先定义一个函数
12 2.添加函数名do_setup2到flask的app对象里面,把过滤器函数名字'xx'传给模板文件
13 3.在模板文件中取出过滤器函数名字 'xx'
14 
15 注意:在模板中只是使用过滤器,并不能自定义过滤器,自定义是在.py文件中进行
16 """
17 
18 
19 # pycharm原生格式化代码:ctrl + alt + l
20 # 目前自己使用的:shift + alt + f
21 
22 @app.route('/')
23 def index():
24     return render_template('demo3.html')
25 
26 
27 # 自定义filter,每隔一个切割一次
28 def do_setup2(my_list):
29     # my_list是前端传来的数据 [11,21,3,4,5,6,9]
30     return my_list[::2]
31 
32 
33 # 在模板里面添加一个过滤器
34 # 第一个参数:表示自定义函数的名字,
35 # 第二个参数:表示在模板里面使用的过滤器的名字
36 app.add_template_filter(do_setup2, 'xx')
37 
38 if __name__ == '__main__':
39     app.run()

对应的HTML:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>自定义filter</title>
 6 </head>
 7 <body>
 8 {#{{ xx:自定义 }}#}
 9 <p>对列表进行切片:{{ [11,21,3,4,5,6,9]|xx }}</p>
10 </body>
11 </html>

控制代码块:

 1 from flask import Flask, render_template
 2 
 3 app = Flask(__name__)
 4 
 5 """
 6 控制代码块主要包含两个:
 7 - if/else if /else / endif
 8 - for / endfor
 9 """
10 
11 
12 @app.route('/')
13 def index():
14     my_list = [
15         {
16             "id": 1,
17             "value": "我爱工作"
18         },
19         {
20             "id": 2,
21             "value": "工作使人快乐"
22         },
23         {
24             "id": 3,
25             "value": "沉迷于工作无法自拔"
26         },
27         {
28             "id": 4,
29             "value": "日渐消瘦"
30         },
31         {
32             "id": 5,
33             "value": "以梦为马,越骑越傻"
34         }
35     ]
36     return render_template('demo4.html', my_list=my_list)
37 
38 
39 if __name__ == '__main__':
40     app.run(debug=True)

对应的HTML:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>控制代码块</title>
 6 </head>
 7 <body>
 8 <h1>控制语句</h1>
 9 {# 专门给for循环使用 loop.....#}
10 {% for item in my_list %}
11     {% if loop.index==1 %}
12         <li style="background-color: deeppink">{{ item.value }}</li>
13     {% elif loop.index==2 %}
14         <li style="background-color:greenyellow">{{ item.value }}</li>
15         {# 注意: else loop.index==3 这样是错误的写法,jinja2模板语法会报错: jinja2.exceptions.TemplateSyntaxError: expected token 'end of statement block', got 'loop'
16 正确写法: {% else %} else就是表示最后一个了,不再需要加loop.index进行判断
17 #}
18     {% else %}
19         <li style="background-color:red">{{ item.value }}</li>
20     {% endif %}
21 {% endfor %}
22 
23 
24 </body>
25 </html>

发送消息flash:

 1 from flask import Flask, flash, render_template
 2 
 3 """
 4 flash:作用:表示发送消息,往队列里面发送
 5 flash是闪电的意思
 6 
 7 类似前端里面的提示消息
 8 
 9 使用场景:
10 在页面需要展示后端发送过来的消息的时候,进行使用,提示用户
11 
12 
13 扩展:
14 1.因为在发送消息的时候使用session,会存储一些隐私数据,比如购物车,为了安全起见,
15 在flask中如果使用到session,都必须加密,使用secret_key进行加密
16 """
17 
18 app = Flask(__name__)
19 
20 # 加密口令,config['SECRET_KEY'] 注意:config里面的key必须大写
21 # ['SECRET_KEY'] 必须遵循config配置文件中默认的写法
22 # RuntimeError: the session is unavailable because no secret key was set.
23 # Set the secret_key on the application to something unique and secret.
24 # 设置秘钥不能为空,否则报错
25 # app.config['SECRET_KEY'] = ''
26 # 专业术语叫salt加盐
27 app.config['SECRET_KEY'] = 'shdfsjk'
28 
29 # 加密之后再加密,再加密,至少十几次。银行密码6位数字的情况下。
30 # 专业术语叫做:加盐salt 加密
31 """
32 常用的加密算法:MD5,SHA1,BASE64等等
33 注意:MD5是不可逆的,即MD5加密之后,不会反向破解出来
34 
35 撞库:
36 
37 """
38 
39 
40 @app.route('/')
41 def index():
42     # 内置对象,不需要传递
43     flash("用户名不正确")
44     flash("用户名不正确")
45     flash("用户名不正确")
46     flash("用户名不正确")
47     return render_template('demo6.html')
48 
49 
50 if __name__ == '__main__':
51     app.run(debug=True)

对应的HTML:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8 {# get_flashed_messages 这是一个函数地址,加()才是一个函数,返回值是flashes
 9 
10 具体作用:Pulls all flashed messages from the session and returns them.
11 #}
12 {% for msg in get_flashed_messages() %}
13 <p>{{ msg }}</p>
14 {% endfor %}
15 
16 </body>
17 </html>

message消息:

 1 from flask import Flask, flash,render_template, request, get_flashed_messages
 2 
 3 """
 4 get_flashed_messages():
 5 
 6 message是一个基于Session实现的用于保存数据的集合,其特点是:使用一次就删除
 7 用来存放临时值
 8 """
 9 app = Flask(__name__)
10 app.secret_key = 'some_secret'
11 
12 
13 @app.route('/')
14 def index1():
15     # 12.获取消息
16     v = get_flashed_messages()
17     print(v)
18     return render_template('index1.html')
19 
20 
21 # 设置完之后,只能通过浏览器访问一次刚刚设置的值,访问完之后就不能再第二次访问了
22 @app.route('/set')
23 def index2():
24     v = request.args.get('p')
25     # 设置设置消息
26     flash(v)
27     return 'ok'
28 
29 
30 if __name__ == "__main__":
31     app.run()

对应的HTML:

 1 <!DOCTYPE html>
 2 <html>
 3 <head lang="en">
 4     <meta charset="UTF-8">
 5     <title></title>
 6 </head>
 7 <body>
 8     <h1>这是index1页面</h1>
 9     {% with messages = get_flashed_messages() %}
10         {% if messages %}
11         <ul class=flashes>
12             {% for message in messages %}
13             <li>{{ message }}</li>
14             {% endfor %}
15         </ul>
16         {% endif %}
17     {% endwith %}
18 </body>
19 </html>

模板继承:

 1 from flask import Flask,render_template
 2 
 3 """
 4 模板继承:复用
 5 
 6 如果子类需要继承父类,就在父类加一个block
 7 
 8 {% block content %}
 9 
10 {% endblock %}
11 
12 
13 子类需要继承父类:
14 
15 {% block content %}
16 <h1>子类的内容</h1>
17 {% endblock %}
18 
19 
20 需要注意:block里面的内容,子类和父类必须保证一样,用来识别是哪一个内容被修改
21 
22 
23 
24 在子类中写{% extends "demo8_father.html" %},
25 如果子类和父类数据不一样,添加block ...
26 """
27 
28 app = Flask(__name__)
29 
30 
31 @app.route('/')
32 def index():
33     return render_template('demo7_son.html')
34 
35 
36 if __name__ == '__main__':
37     app.run()

对应的HTML:

demo7_son:

1 {% extends "demo8_father.html" %}
2 
3 {% block content %}
4 <h1>子类的内容页面</h1>
5 {% endblock %}

demo8_father:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8 <h1>父类的顶部</h1>
 9 
10 {% block content %}
11 <h1>父类的内容</h1>
12 {% endblock %}
13 
14 <h1>父类的底部</h1>
15 </body>
16 </html>

命令行方式执行程序:

 1 from flask import Flask
 2 from flask_script import Manager
 3 
 4 # Manager可以用来管理我们的应用程序
 5 app = Flask(__name__)
 6 # 创建一个flask的脚本,传输一个flask对象,把app对象交给manager管理  注意:需要传参数app
 7 manager = Manager(app)
 8 """
 9 因为公司里面都是脚本命令行操作
10 """
11 
12 
13 @app.route('/')
14 def index():
15     # index是视图函数
16     return 'index'
17 
18 
19 if __name__ == '__main__':
20     manager.run()
21 

内置对象:

 1 from flask import Flask, render_template, g, url_for
 2 
 3 app = Flask(__name__)
 4 
 5 """
 6 g变量就是一个容器,内置对象,不需要手动传
 7 
 8 内置对象:
 9 作用:如果使用内置对象,就不需要手动传递值,直接在页面上面使用即可
10 只是为了方便取值.
11 因为在模板页面里面已经把这些变量定义好了
12 
13 g表示一个容器,里面可以存储值
14 格式: g.变量名   其中变量名可以随便取
15 """
16 
17 
18 @app.route('/')
19 def index():
20     g.name = 'heima'
21     return render_template('demo5.html')
22 
23 
24 if __name__ == '__main__':
25     app.run()

对应的HTML:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8 <h1>特有内置对象</h1>
 9 <p>获取内置的debug对象:{{ config.DEBUG }}</p>
10 <p>获取内置的请求的url:{{ request.url }}</p>
11 <p>获取内置的url_for对象:{{ url_for.url }}</p>
12 <p>获取内置的g变量里面的数据:{{ g.name }}</p>
13 </body>
14 </html>

内置的config默认信息:

原文地址:https://www.cnblogs.com/huaibin/p/9851359.html