zoukankan      html  css  js  c++  java
  • 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默认信息:

  • 相关阅读:
    BZOJ3573: [Hnoi2014]米特运输
    BZOJ3531: [Sdoi2014]旅行
    BZOJ3505: [Cqoi2014]数三角形
    BZOJ3309: DZY Loves Math
    BZOJ3260: 跳
    BZOJ3252: 攻略
    BZOJ3226: [Sdoi2008]校门外的区间
    BZOJ3155: Preprefix sum
    BZOJ2843: 极地旅行社
    BZOJ2671: Calc
  • 原文地址:https://www.cnblogs.com/huaibin/p/9851359.html
Copyright © 2011-2022 走看看