澳门新萄京官方网站-www.8455.com-澳门新萄京赌场网址

澳门新萄京官方网站:Flask首要知识点

2019-06-08 作者:www.8455.com   |   浏览(135)

一、flask

Python之flask总结,pythonflask

一、flask

     a、Flask是一个基于Python开采并且依赖jinja二模板和Werkzeug WSGI服务的一个Mini框架,对于Werkzeug本质是Socket服务端,其用来收纳http请求并对请求进行预管理,然后触发Flask框架,开采人士基于Flask框架提供的功效对请求实行相应的拍卖,并赶回给用户,假使要重回给用户复杂的从头到尾的经过时,要求借助jinja二模板来兑现对模板的拍卖,即:将模板和数码开始展览渲染,将渲染后的字符串再次来到给用户浏览器

     b、“微”(micro) 并不意味着您要求把全体 Web 应用塞进单个 Python 文件(固然真正能够 ),也不表示 Flask 在效益上全体欠缺。微框架中的“微”意味着 Flask 目的在于保持主旨简单而轻巧增添。Flask 不会替你做出太多决策——比方动用何种数据库。而那二个 Flask 所选用的——举个例子利用何种模板引擎——则很轻巧替换。除却的满贯都由可由你掌握。如此,Flask 能够与你相辅相成。

     c、私下认可情形下,Flask 不带有数据库抽象层、表单验证,或是其它任何已有多样库能够胜任的功用。但是,Flask 援助用扩展来给使用增多这个职能,就像是 Flask 本身完毕的如出壹辙。众多的扩充提供了数据库集成、表单验证、上传管理、各式各样的盛开认证技术等效果。Flask 只怕是“微小”的,但它已预备幸好须要繁杂的生产条件中投入使用。

二、安装

      a、安装:pip3 install flask**

3、虚拟碰着

**      a、安装: pip3 install virtualenv**

      b、# 创设虚拟遭遇 virtualenv env1

      c、# 进入虚拟遭逢 Scripts/activate

      d、 # 退出虚拟景况 Scripts/deactivate

四、flask框架**

**      a、简单介绍:轻量级框架                      Django:无socket、中间件、路由系统、视图(CBV,FBV)、 模板、OPRADOM、cookie、Session、Admin、Form、缓存、数字信号、种类化....                      Flask:无socket、中间件(扩展)、路由系统、视图(CBV)、第2方模板(jinja2)、cookie、Session弱爆了**

**      b、 什么是wsgi?
                           Web服务网管接口,协议。**

**      c、Flask重视几个达成了WSGI协议的模块:werkzeug**

五、flask

       a、 -依赖于wsgi模块:wsgiref,werkzeug,wsgi

       b、  -实例化Flask对象

                  -静态文件前缀  /xxx

                  -静态文件目录

                  -模板路线

        c、 增添路由关系      

                  -将 Rule(url和视图函数)加多到Flask对象的url_map字段中

                  -二种增多路由的方式

        d、request

                 -request.form

                 -request.args 

6、基本使用

from flask import Flask

# 实例化Flask对象
app = Flask(__name__)

# 生成路由关系,并把关系保存到某个地方,app对象的 url_map字段中
@app.route('/xxxx')  # @decorator
def index():
    return "Index"

# def index():
#     return "Index"
# app.add_url_rule('/xxx', "n1", index)

if __name__ == '__main__':
    # 启动程序,监听用户请求
    # 一旦请求到来,执行 app.__call__方法
    # 封装用户请求
    # 进行路由匹配
    app.run()

     a、封存session的多寡存到了浏览器上,
        - 优点:缓和了服务端的压力
        - 缺点:不安全

     b、路由系统:  

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

七、路由系统**

**     a、  -可传唱参数**     **

            @app.route('/user/<username>')

            @qpp.route('/post/<int:post_id>',methods=['GET','POST'],endpoint='fff')

     b、反向生成U奥德赛L:url_for**

     c、恢宏Flask的路由系统,让它辅助正则:**

from flask import Flask,url_for

                app = Flask(__name__)

                # 定义转换的类
                from werkzeug.routing import BaseConverter
                class RegexConverter(BaseConverter):
                    """
                    自定义URL匹配正则表达式
                    """

                    def __init__(self, map, regex):
                        super(RegexConverter, self).__init__(map)
                        self.regex = regex

                    def to_python(self, value):
                        """
                        路由匹配时,匹配成功后传递给视图函数中参数的值
                        :param value: 
                        :return: 
                        """
                        return int(value)

                    def to_url(self, value):
                        """
                        使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数
                        :param value: 
                        :return: 
                        """
                        val = super(RegexConverter, self).to_url(value)
                        return val

                # 添加到converts中
                app.url_map.converters['xxx'] = RegexConverter

                # 进行使用
                @app.route('/index/<xxx("d "):nid>',endpoint='xx')
                def index(nid):
                    url_for('xx',nid=123)
                    return "Index"

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

8、请求响应

from flask import Flask
    from flask import request
    from flask import render_template
    from flask import redirect
    from flask import make_response

    app = Flask(__name__)


    @app.route('/login.html', methods=['GET', "POST"])
    def login():

        # 请求相关信息
        # request.method
        # request.args
        # request.form
        # request.values
        # request.cookies
        # request.headers
        # request.path
        # request.full_path
        # request.script_root
        # request.url
        # request.base_url
        # request.url_root
        # request.host_url
        # request.host
        # request.files
        # obj = request.files['the_file_name']
        # obj.save('/var/www/uploads/'   secure_filename(f.filename))

        # 响应相关信息
        # return "字符串"
        # return render_template('html模板路径',**{})
        # return redirect('/index.html')

        # response = make_response(render_template('index.html'))
        # response是flask.wrappers.Response类型
        # response.delete_cookie('key')
        # response.set_cookie('key', 'value')
        # response.headers['X-Something'] = 'A value'
        # return response


        return "内容"

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

    a、在django中用make_safe而在Flask中用make_response

九、模板语言   **

     a、模板的使用

               Flask使用的是Jinja二模板,所以其语法和Django一点差异也未有

     b、自定义模板方法

               Flask中自定义模板方法的格局和Bottle相似,创建二个函数并透过参数的款型传播render_template,

十、session 

      a、 -session是或不是还有别的措施?

                     -它与字典方法一样

      b、  -session超时时间怎么设置:**

app.config['SESSION_COOKIE_NAME'] = 'session_lvning'
            """
            'SESSION_COOKIE_NAME':                  'session',
            'SESSION_COOKIE_DOMAIN':                None,
            'SESSION_COOKIE_PATH':                  None,
            'SESSION_COOKIE_HTTPONLY':              True,
            'SESSION_COOKIE_SECURE':                False,
            'SESSION_REFRESH_EACH_REQUEST':         True,
            'PERMANENT_SESSION_LIFETIME':           timedelta(days=31)

     c、除请求对象之外,还有一个 session 对象。它同意你在区别请求间存款和储蓄特定用户的音讯。它是在 Cookies 的根基上贯彻的,并且对 Cookies 举行密钥具名要选用会话,你须要设置二个密钥。

     d、

  • 设置:session['username'] = 'xxx'

  • 删除:session.pop('username', None)

十一、闪现(flash)**

     a、session从在在服务端的贰个字典中,session保存的数目取叁回,它依旧会有。而flash是依照session制造的,flash帮衬在里头放值,只要在里头取值它就能并未有。闪现就是**

     b、在session的根基上,把它的值真实的位于session上,当去它的时候不仅仅把它的值取走,还把session的东西去掉。

十二、蓝图**

     a、蓝图用于为运用提供目录划分**

  • 蓝图URL前缀:xxx = Blueprint('account', __name__,url_prefix='/xxx')
  • 蓝图子域名:xxx = Blueprint('account', __name__,subdomain='admin')
    # 前提须要给配备SETiguanVESportage_NAME: app.config['SERVER_NAME'] = 'wupeiqi.com:5000'
    # 访问时:admin.wupeiqi.com:5000/login.html

十三、DBUtils**

      a、DBUtils是Python的一个用于落到实处数据库连接池的模块。**

      b、连接池的三种形式:**

            (一)、第2种方式:

                                 它的症结:每二回呼吁反复创制数据库的链接,链接的次数太多

             (2)、第两种方式:

                                 它的缺陷:不可能协助并发

              (叁)、第三种形式:

                                它是根据DBUtils完成数据库连接池

                                        -为各种线程创立1个链接,该线程关闭时,不是当真的关闭,本线程再一次调用时,依然选择的最开始的创导的链接,知道线程终止,数据库链接才关闭

                                       -创造2个连接池(十一个链接),为保有线程提供链接,使用时来拓展获取,使用达成时,再度放回到连接池。

       c、DBUtils的应用:**

import time
import pymysql
import threading
from DBUtils.PooledDB import PooledDB, SharedDBConnection
POOL = PooledDB(
    creator=pymysql,  # 使用链接数据库的模块
    maxconnections=6,  # 连接池允许的最大连接数,0和None表示不限制连接数
    mincached=2,  # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
    maxcached=5,  # 链接池中最多闲置的链接,0和None不限制
    maxshared=3,  # 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。
    blocking=True,  # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
    maxusage=None,  # 一个链接最多被重复使用的次数,None表示无限制
    setsession=[],  # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
    ping=0,
    # ping MySQL服务端,检查是否服务可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always
    host='127.0.0.1',
    port=3306,
    user='root',
    password='123',
    database='pooldb',
    charset='utf8'
)

十四、session

      a、 session和cookie的规律和区分:

               cookie是保留在浏览器上的键值对
               session是存在服务端的键值对(服务端的session正是2个大字典,字典中是随机字符串)(session与request原理同样)(session原理跟上下文也会有关联)

               session依赖于cookie存在**

**      b、  session流程**      **

当请求第一次进来,生成随机字符串
                  -发给用户cookie
                  -保存到session字典中时
                  它调用stark将随机字符串和对应的值放到local
                视图函数
                 -使用时导入用top(它拿的是session)
                     session=LocalProxy(partile(_lookup_req_object,'session '))
               请求处理完毕:
                     内存处理完毕后,将session做持久化(session存到数据库,存到Redis,存到加密的cookie中)

十五、session源码分析

     a、先执行Flask的__call__方法 ,调用出来wsgi_app,它先做request的上下文做完,请求刚进来到push中,它先管理request将呼吁相关的数额,然后增添到了local中,

     b、 紧接着管理session(将RequestContext对象(request,session)增多到local中),request(将request音信打包到Request(environ)对象并复制给requestContext 对                       象),然后拿走cookie中的随机字符串,核查是否有,未有就更换。依照随便字符串,获取服务端session保存的值。把session放到内部存储器中,

     c、  执行wsgi_app方法下边包车型地铁视图函数。实践完视图函数重临到full_dispatch_requesthong ,触发只进行二回的装饰器中(触发Flask时域信号),

     d、  实行完这么些装饰器,紧接着实行下边包车型大巴例外的装饰器,假使这一个分外装饰器未有重临值,那么rv=None,假如有再次来到值,页面时就体现这一个重回值,

     e、假使未有重临值,触发实行那几个视图函数,拿重临值。请求试行完重回后,调用finalize_request,对它的重临值进行打包。

十六、Flask和Django的区别 

     a、伸手相关的多少           

                  -Django:参数

                  -Flask:    基于Local,LocalStark对象

     b、 几个请求进入会不会搅乱            

                  -单线程

                  -多线程

                  -协程

                    解决: from greenlet import getcurrent as get_ident

十七、**Flask**信号

    a、 Flask框架中的连续信号基于blinker**

    b、安装: pip3 install blinker**

    c、拾一个时域信号

1. 内置信号
            10个信号:
                2. request_started = _signals.signal('request-started')                # 请求到来前执行
                5. request_finished = _signals.signal('request-finished')              # 请求结束后执行

                3. before_render_template = _signals.signal('before-render-template')  # 模板渲染前执行
                4. template_rendered = _signals.signal('template-rendered')            # 模板渲染后执行

                2/3/4/5或不执行 got_request_exception = _signals.signal('got-request-exception')    # 请求执行出现异常时执行

                6. request_tearing_down = _signals.signal('request-tearing-down')      # 请求执行完毕后自动执行(无论成功与否)
                7. appcontext_tearing_down = _signals.signal('appcontext-tearing-down')# 请求上下文执行完毕后自动执行(无论成功与否)


                1. appcontext_pushed = _signals.signal('appcontext-pushed')            # 请求app上下文push时执行

                8. appcontext_popped = _signals.signal('appcontext-popped')            # 请求上下文pop时执行

                message_flashed = _signals.signal('message-flashed')                   # 调用flask在其中添加数据时,自动触发

     d、flask数字信号本生本身并未有,用的是旁人的,并且这么些非能量信号通过装饰器全体足以代替了的,可是Django里面某个特殊的
就是这么些model操作根本未有装饰器,正是同过内置的功率信号来成功的

十八、django内置的时域信号

Request/response signals
                    request_started             # 请求到来前,自动触发
                    request_finished            # 请求结束后,自动触发
                    got_request_exception       # 请求异常后,自动触发

                Model signals
                    pre_init                    # django的modal执行其构造方法前,自动触发
                    post_init                   # django的modal执行其构造方法后,自动触发

                    pre_save                    # django的modal对象保存前,自动触发
                    post_save                   # django的modal对象保存后,自动触发

                    pre_delete                  # django的modal对象删除前,自动触发
                    post_delete                 # django的modal对象删除后,自动触发

                    m2m_changed                 # django的modal中使用m2m字段操作第三张表(add,remove,clear)前后,自动触发

                    class_prepared              # 程序启动时,检测已注册的app中modal类,对于每一个类,自动触发

                Management signals
                    pre_migrate                 # 执行migrate命令前,自动触发
                    post_migrate                # 执行migrate命令后,自动触发

                Test signals
                    setting_changed             # 使用test测试修改配置文件时,自动触发
                    template_rendered           # 使用test测试渲染模板时,自动触发
                Database Wrappers
                    connection_created          # 创建数据库连接时,自动触发

十九、Wtform

    a、WTForms是2个支撑四个web框架的form组件,首要用于对用户请求数据开展表达。

    b、安装: pip3 install wtform

    c、用途:**

**       1、用户登录注册**

               当用户登陆时候,须求对用户提交的用户名和密码实行各类格式校验。如:

              用户不能够为空;用户长度必须大于6;

              密码无法为空;密码长度必须超越12;密码必须带有 字母、数字、特殊字符等(自定义正则);

澳门新萄京官方网站 1

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Flask, render_template, request, redirect
from wtforms import Form
from wtforms.fields import core
from wtforms.fields import html5
from wtforms.fields import simple
from wtforms import validators
from wtforms import widgets

app = Flask(__name__, template_folder='templates')
app.debug = True


class LoginForm(Form):
    name = simple.StringField(
        label='用户名',
        validators=[
            validators.DataRequired(message='用户名不能为空.'),
            validators.Length(min=6, max=18, message='用户名长度必须大于%(min)d且小于%(max)d')
        ],
        widget=widgets.TextInput(),
        render_kw={'class': 'form-control'}

    )
    pwd = simple.PasswordField(
        label='密码',
        validators=[
            validators.DataRequired(message='密码不能为空.'),
            validators.Length(min=8, message='用户名长度必须大于%(min)d'),
            validators.Regexp(regex="^(?=.*[a-z])(?=.*[A-Z])(?=.*d)(?=.*[[email protected]$!%*?&])[A-Za-z[email protected]$!%*?&]{8,}",
                              message='密码至少8个字符,至少1个大写字母,1个小写字母,1个数字和1个特殊字符')

        ],
        widget=widgets.PasswordInput(),
        render_kw={'class': 'form-control'}
    )



@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        form = LoginForm()
        return render_template('login.html', form=form)
    else:
        form = LoginForm(formdata=request.form)
        if form.validate():
            print('用户提交数据通过格式验证,提交的值为:', form.data)
        else:
            print(form.errors)
        return render_template('login.html', form=form)

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

app.py 澳门新萄京官方网站 2

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>登录</h1>
<form method="post">
    <!--<input type="text" name="name">-->
    <p>{{form.name.label}} {{form.name}} {{form.name.errors[0] }}</p>

    <!--<input type="password" name="pwd">-->
    <p>{{form.pwd.label}} {{form.pwd}} {{form.pwd.errors[0] }}</p>
    <input type="submit" value="提交">
</form>
</body>
</html>

login

二十、SQLALchemy

    a、介绍 :      

           SQLALchemy是两个基于Python达成的O奥迪Q7M框架。该框架是起家在DB API之上,使用关系对象映射进行数据库操作

           简言之便就是:将类和对象转变到SQL,然后使用数据API实践SQL并赢得施行的结果

    b、安装: pip3 install SQLALchemy

    c、组成都部队分**

 engine,                                     框架的引擎

     Connection  Pooling  ,                      数据库连接池

     Dialect,                                    选择链接数据库的DB  API种类

     Schema /Types,                              架构和类型     

     SQL Exprression Language,                   SQL表达式语言

    d、SQLALcheam省内不只怕操作数据库,其必须来pymysql品级一方插件, Dialect用于数据API的沟通,根据布署文件的不等**

调用分化的数据库API,从而达成对数据库的操作

MySQL-Python
    mysql mysqldb://<user>:<password>@<host>[:<port>]/<dbname>

pymysql
    mysql pymysql://<username>:<password>@<host>/<dbname>[?<options>]

MySQL-Connector
    mysql mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname>

cx_Oracle
    oracle cx_oracle://user:pass@host:port/dbname[?key=value&key=value...]

更多:http://docs.sqlalchemy.org/en/latest/dialects/index.html

 

 

  

 

一、flask a、Flask是二个遵照Python开辟并且信赖jinja二模板和Werkzeug WSGI服务的2个微型框架,对于Werkzeug本质是Sock...

1.Flask:

1.Flask:

  Flask是一个遵照Python开采并且依赖jinja二模板和Werkzeug WSGI服务的四个Mini框架,对于Werkzeug本质是Socket服务端,其用于收纳http请求并对请求举办预管理,然后触发Flask框架,开拓职员基于Flask框架提供的法力对请求举办相应的拍卖,并赶回给用户,假诺要回去给用户复杂的源委时,须求借助jinja二模板来落到实处对模板的管理,即:将模板和数量实行渲染,将渲染后的字符串重返给用户浏览器。

     a、Flask是三个基于Python开辟并且正视jinja2模板和Werkzeug WSGI服务的三个小型框架,对于Werkzeug本质是Socket服务端,其用于吸收接纳http请求并对请求实行预管理,然后触发Flask框架,开垦人士基于Flask框架提供的机能对请求举办对应的处理,并重返给用户,纵然要回到给用户复杂的剧情时,需求借助jinja二模板来实现对模板的拍卖,即:将模板和数目进行渲染,将渲染后的字符串重返给用户浏览器

Flask是一个基于Python开垦并且正视jinja贰模板和Werkzeug WSGI服务的三个Mini框架,对于Werkzeug本质是Socket服务端,其用来吸收接纳http请求并对请求实行预管理,然后触发Flask框架,开荒职员基于Flask框架提供的机能对请求举行对应的管理,并赶回给用户,借使要重临给用户复杂的开始和结果时,须要借助jinja二模板来兑现对模板的拍卖,即:将模板和数码举行渲染,将渲染后的字符串重返给用户浏览器。

Flask是1个依照Python开辟并且重视jinja2模板和Werkzeug WSGI服务的贰个小型框架,对于Werkzeug本质是Socket服务端,其用于收纳http请求并对请求进行预管理,然后触发Flask框架,开垦人员基于Flask框架提供的法力对请求进行相应的管理,并赶回给用户,假诺要重回给用户复杂的源委时,须要借助jinja二模板来贯彻对模板的管理,即:将模板和多少举办渲染,将渲染后的字符串重临给用户浏览器。

  “微”(micro) 并不意味着您需求把全部 Web 应用塞进单个 Python 文件(纵然真正能够 ),也不表示 Flask 在效益上有着欠缺。微框架中的“微”意味着 Flask 目的在于维持核心轻松而轻巧增加。Flask 不会替你做出太多决策——举个例子利用何种数据库。而那么些 Flask 所选用的——比方采纳何种模板引擎——则很轻便替换。除外的凡事都由可由你调节。如此,Flask 能够与你相得益彰。

     b、“微”(micro) 并不表示您要求把全体Web 应用塞进单个 Python 文件(固然真正能够 ),也不意味着 Flask 在效率上具有欠缺。微框架中的“微”意味着 Flask 意在维持大旨轻巧而轻松扩充。Flask 不会替你做出太多决策——比方利用何种数据库。而那么些 Flask 所接纳的——比如采纳何种模板引擎——则很轻易替换。除此而外的任何都由可由你调控。如此,Flask 能够与你相辅相成。

“微”(micro) 并不代表你需求把全部 Web 应用塞进单个 Python 文件(即使真正可以),也不意味 Flask 在功用上有着欠缺。微框架中的“微”意味着 Flask 目的在于维持大旨不难而易于扩张。Flask 不会替你做出太多决策——譬如利用何种数据库。而那一个 Flask 所接纳的——比方接纳何种模板引擎——则很轻易替换。除却的百分百都由可由你调控。如此,Flask 能够与您相辅相成。

“微”(micro) 并不意味你需求把全部 Web 应用塞进单个 Python 文件(即便真正能够),也不代表 Flask 在成效上具备欠缺。微框架中的“微”意味着 Flask 目的在于维持核心简单而易于扩张。Flask 不会替你做出太多决策——比方利用何种数据库。而那么些 Flask 所挑选的——比如选拔何种模板引擎——则很轻便替换。除外的一体都由可由你左右。如此,Flask 能够与您相辅相成。

暗许景况下,Flask 不含有数据库抽象层、表单验证,或是别的任何已有两种库能够胜任的效率。但是,Flask 帮助用扩大来给使用增添那几个作用,就像是 Flask 自己实现的大同小异。众多的恢弘提供了数据库集成、表单验证、上传处理、精彩纷呈的盛开认证技艺等效果。Flask 只怕是“微小”的,但它已计划幸好供给繁杂的生产条件中投入使用。

     c、暗中认可意况下,Flask 不含有数据库抽象层、表单验证,或是别的任何已有二种库可以胜任的职能。但是,Flask 辅助用扩张来给使用增多这一个作用,就如是 Flask 自己达成的同一。众多的扩充提供了数据库集成、表单验证、上传管理、有滋有味的盛开认证工夫等作用。Flask 大概是“微小”的,但它已常备不懈还好须要繁杂的生产情状中投入使用。

暗许情状下,Flask 不含有数据库抽象层、表单验证,或是别的任何已有四种库能够胜任的效率。可是,Flask 帮助用扩充来给使用增加这么些意义,就如是 Flask 本身达成的等同。众多的扩展提供了数据库集成、表单验证、上传处理、精彩纷呈的盛开认证本领等功能。Flask 大概是“微小”的,但它已希图辛亏须求繁杂的生产条件中投入使用。

暗中同意境况下,Flask 不带有数据库抽象层、表单验证,或是别的任何已有三种库能够胜任的功用。但是,Flask 接济用增添来给使用增多那几个职能,就好像是 Flask 自己完毕的一模2样。众多的扩大提供了数据库集成、表单验证、上传管理、各式各样的盛开认证技能等效果。Flask 也许是“微小”的,但它已策画辛亏供给繁杂的生产条件中投入使用。

?

二、安装

安装:pip3 install flask

安装:pip3 install flask

1
pip3 install flask

      a、安装:pip3 install flask**

 

 

澳门新萄京官方网站 3澳门新萄京官方网站 4

叁、虚拟情况

澳门新萄京官方网站 5澳门新萄京官方网站 6

澳门新萄京官方网站 7澳门新萄京官方网站 8

from werkzeug.wrappers import Request, Response

@Request.application
def hello(request):
    return Response('Hello World!')

if __name__ == '__main__':
    from werkzeug.serving import run_simple
    run_simple('localhost', 4000, hello)

*澳门新萄京官方网站,*      a、安装: pip3 install virtualenv**

from werkzeug.wrappers import Request, Response

@Request.application
def hello(request):
    return Response('Hello World!')

if __name__ == '__main__':
    from werkzeug.serving import run_simple
    run_simple('localhost', 4000, hello)

werkzeug
from werkzeug.wrappers import Request, Response

@Request.application
def hello(request):
    return Response('Hello World!')

if __name__ == '__main__':
    from werkzeug.serving import run_simple
    run_simple('localhost', 4000, hello)

werkzeug

werkzeug

      b、# 创设虚拟意况 virtualenv env1

View Code

View Code

一. 大旨采取

?

1
2
3
4
5
6
7
8
9
from flask import Flask
app = Flask(__name__)
 
@app.route('/')
def hello_world():
    return 'Hello World!'
 
if __name__ == '__main__':
    app.run()

      c、# 进入虚拟碰到 Scripts/activate

 

 

贰、配置文件

澳门新萄京官方网站 9澳门新萄京官方网站 10

flask中的配置文件是一个flask.config.Config对象(继承字典),默认配置为:
    {
        'DEBUG':                                get_debug_flag(default=False),  是否开启Debug模式
        'TESTING':                              False,                          是否开启测试模式
        'PROPAGATE_EXCEPTIONS':                 None,                          
        'PRESERVE_CONTEXT_ON_EXCEPTION':        None,
        'SECRET_KEY':                           None,
        'PERMANENT_SESSION_LIFETIME':           timedelta(days=31),
        'USE_X_SENDFILE':                       False,
        'LOGGER_NAME':                          None,
        'LOGGER_HANDLER_POLICY':               'always',
        'SERVER_NAME':                          None,
        'APPLICATION_ROOT':                     None,
        'SESSION_COOKIE_NAME':                  'session',
        'SESSION_COOKIE_DOMAIN':                None,
        'SESSION_COOKIE_PATH':                  None,
        'SESSION_COOKIE_HTTPONLY':              True,
        'SESSION_COOKIE_SECURE':                False,
        'SESSION_REFRESH_EACH_REQUEST':         True,
        'MAX_CONTENT_LENGTH':                   None,
        'SEND_FILE_MAX_AGE_DEFAULT':            timedelta(hours=12),
        'TRAP_BAD_REQUEST_ERRORS':              False,
        'TRAP_HTTP_EXCEPTIONS':                 False,
        'EXPLAIN_TEMPLATE_LOADING':             False,
        'PREFERRED_URL_SCHEME':                 'http',
        'JSON_AS_ASCII':                        True,
        'JSON_SORT_KEYS':                       True,
        'JSONIFY_PRETTYPRINT_REGULAR':          True,
        'JSONIFY_MIMETYPE':                     'application/json',
        'TEMPLATES_AUTO_RELOAD':                None,
    }

方式一:
    app.config['DEBUG'] = True

    PS: 由于Config对象本质上是字典,所以还可以使用app.config.update(...)

方式二:
    app.config.from_pyfile("python文件名称")
        如:
            settings.py
                DEBUG = True

            app.config.from_pyfile("settings.py")

    import os
    os.environ['FLAKS-SETTINGS'] = 'settings.py'
    app.config.from_envvar("环境变量名称")
        环境变量的值为python文件名称名称,内部调用from_pyfile方法


    app.config.from_json("json文件名称")
        JSON文件名称,必须是json格式,因为内部会执行json.loads

    app.config.from_mapping({'DEBUG':True})
        字典格式

    app.config.from_object("python类或类的路径")

        app.config.from_object('pro_flask.settings.TestingConfig')

        settings.py

            class Config(object):
                DEBUG = False
                TESTING = False
                DATABASE_URI = 'sqlite://:memory:'

            class ProductionConfig(Config):
                DATABASE_URI = 'mysql://user@localhost/foo'

            class DevelopmentConfig(Config):
                DEBUG = True

            class TestingConfig(Config):
                TESTING = True

        PS: 从sys.path中已经存在路径开始写


    PS: settings.py文件默认路径要放在程序root_path目录,如果instance_relative_config为True,则就是instance_path目录

View Code

 

      d、 # 退出虚拟境遇 Scripts/deactivate

2. 虚拟意况

2. 虚拟境况

3、路由系统

  • @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
2
3
4
5
6
7
8
9
DEFAULT_CONVERTERS = {
    'default':          UnicodeConverter,
    'string':           UnicodeConverter,
    'any':              AnyConverter,
    'path':             PathConverter,
    'int':              IntegerConverter,
    'float':            FloatConverter,
    'uuid':             UUIDConverter,
}

澳门新萄京官方网站 11澳门新萄京官方网站 12

        def auth(func):
            def inner(*args, **kwargs):
                print('before')
                result = func(*args, **kwargs)
                print('after')
                return result

        return inner

        @app.route('/index.html',methods=['GET','POST'],endpoint='index')
        @auth
        def index():
            return 'Index'

        或

        def index():
            return "Index"

        self.add_url_rule(rule='/index.html', endpoint="index", view_func=index, methods=["GET","POST"])
        or
        app.add_url_rule(rule='/index.html', endpoint="index", view_func=index, methods=["GET","POST"])
        app.view_functions['index'] = index


        或
        def auth(func):
            def inner(*args, **kwargs):
                print('before')
                result = func(*args, **kwargs)
                print('after')
                return result

        return inner

        class IndexView(views.View):
            methods = ['GET']
            decorators = [auth, ]

            def dispatch_request(self):
                print('Index')
                return 'Index!'

        app.add_url_rule('/index', view_func=IndexView.as_view(name='index'))  # name=endpoint



        或


        class IndexView(views.MethodView):
            methods = ['GET']
            decorators = [auth, ]

            def get(self):
                return 'Index.GET'

            def post(self):
                return 'Index.POST'


        app.add_url_rule('/index', view_func=IndexView.as_view(name='index'))  # name=endpoint




        @app.route和app.add_url_rule参数:
            rule,                       URL规则
            view_func,                  视图函数名称
            defaults=None,              默认值,当URL中无参数,函数需要参数时,使用defaults={'k':'v'}为函数提供参数
            endpoint=None,              名称,用于反向生成URL,即: url_for('名称')
            methods=None,               允许的请求方式,如:["GET","POST"]


            strict_slashes=None,        对URL最后的 / 符号是否严格要求,
                                        如:
                                            @app.route('/index',strict_slashes=False),
                                                访问 http://www.xx.com/index/ 或 http://www.xx.com/index均可
                                            @app.route('/index',strict_slashes=True)
                                                仅访问 http://www.xx.com/index 
            redirect_to=None,           重定向到指定地址
                                        如:
                                            @app.route('/index/<int:nid>', redirect_to='/home/<nid>')
                                            或
                                            def func(adapter, nid):
                                                return "/home/888"
                                            @app.route('/index/<int:nid>', redirect_to=func)
            subdomain=None,             子域名访问
                                                from flask import Flask, views, url_for

                                                app = Flask(import_name=__name__)
                                                app.config['SERVER_NAME'] = 'wupeiqi.com:5000'


                                                @app.route("/", subdomain="admin")
                                                def static_index():
                                                    """Flask supports static subdomains
                                                    This is available at static.your-domain.tld"""
                                                    return "static.your-domain.tld"


                                                @app.route("/dynamic", subdomain="<username>")
                                                def username_index(username):
                                                    """Dynamic subdomains are also supported
                                                    Try going to user1.your-domain.tld/dynamic"""
                                                    return username   ".your-domain.tld"


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

a.注册路由原理

澳门新萄京官方网站 13澳门新萄京官方网站 14

           from flask import Flask, views, url_for
            from werkzeug.routing import BaseConverter

            app = Flask(import_name=__name__)


            class RegexConverter(BaseConverter):
                """
                自定义URL匹配正则表达式
                """
                def __init__(self, map, regex):
                    super(RegexConverter, self).__init__(map)
                    self.regex = regex

                def to_python(self, value):
                    """
                    路由匹配时,匹配成功后传递给视图函数中参数的值
                    :param value: 
                    :return: 
                    """
                    return int(value)

                def to_url(self, value):
                    """
                    使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数
                    :param value: 
                    :return: 
                    """
                    val = super(RegexConverter, self).to_url(value)
                    return val

            # 添加到flask中
            app.url_map.converters['regex'] = RegexConverter


            @app.route('/index/<regex("d "):nid>')
            def index(nid):
                print(url_for('index', nid='888'))
                return 'Index'


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

b. 自定制正则路由11分

四、flask框架**

安装:   pip3 install virtualenv

        # 创建虚拟环境
        virtualenv env1 

        # 进入虚拟环境
               Scripts/activate

        # 退出虚拟环境
              Scripts/deactivate
安装:   pip3 install virtualenv

        # 创建虚拟环境
        virtualenv env1 

        # 进入虚拟环境
               Scripts/activate

        # 退出虚拟环境
              Scripts/deactivate

4、视图函数

  在Flask中央电台图函数也分为CBV和FBV

FBV

澳门新萄京官方网站 15澳门新萄京官方网站 16

def auth(func):
    def inner(*args, **kwargs):
        result = func(*args, **kwargs)
        return result
    return inner


方式一:
@app.route('/index',endpoint='xx')
@auth
def index(nid):
    url_for('xx',nid=123)
    return "Index"



方式二:                
@auth                
def index(nid):
    url_for('xx',nid=123)
    return "Index"

app.add_url_rule('/index',index)

FBV

CBV

澳门新萄京官方网站 17澳门新萄京官方网站 18

def auth(func):
    def inner(*args, **kwargs):
        result = func(*args, **kwargs)
        return result
    return inner

class IndexView(views.MethodView):
    # methods = ['POST']

    decorators = [auth,]
    def get(self):
        v = url_for('index')
        print(v)
        return "GET"

    def post(self):
        return "GET"

app.add_url_rule('/index', view_func=IndexView.as_view(name='index'))

CBV

 

**      a、简要介绍:轻量级框架                      Django:无socket、中间件、路由系统、视图(CBV,FBV)、 模板、OOdysseyM、cookie、Session、Admin、Form、缓存、功率信号、类别化....                      Flask:无socket、中间件(扩充)、路由系统、视图(CBV)、第二方模板(jinja二)、cookie、Session弱爆了**

3.flask框架

3.flask框架

五、模板

一、模板的采用

  Flask使用的是Jinja二模板,所以其语法和Django未有差距

二、自定义模板方法

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

澳门新萄京官方网站 19澳门新萄京官方网站 20

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <h1>自定义函数</h1>
    {{ww()|safe}}

</body>
</html>

html

澳门新萄京官方网站 21澳门新萄京官方网站 22

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Flask,render_template
app = Flask(__name__)


def wupeiqi():
    return '<h1>Wupeiqi</h1>'

@app.route('/login', methods=['GET', 'POST'])
def login():
    return render_template('login.html', ww=wupeiqi)

app.run()

run.py

澳门新萄京官方网站 23澳门新萄京官方网站 24

from flask import Flask,url_for,request,redirect,render_template,jsonify,make_response,Markup
from urllib.parse import urlencode,quote,unquote
app = Flask(__name__)

def test(a1,a2):
    return a1 a2

#全局视图函数,无需在render_template时传入也可在前端调用
#前端使用方式{{sb(1,2)}}
@app.template_global()
def sb(a1, a2):
    return a1   a2   100


#与上面的全局视图函数相似,无需在render_template时传入也可在前端调用
#前端使用方式{{ 1|db(2,3)}}
@app.template_filter()
def db(a1, a2, a3):
    return a1   a2   a3



@app.route('/index',endpoint='xx')
def index():
    v1 = "字符串"
    v2 = [11,22,33]
    v3 = {'k1':'v1','k2':'v2'}
    v4 = Markup("<input type='text' />")#若不使用Markup,前端需{{v4|safe}}
    return render_template('index.html',v1=v1,v2=v2,v3=v3,v4=v4,test=test)


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

视图函数扩充

澳门新萄京官方网站 25澳门新萄京官方网站 26

{% extends 'layout.html'%}

{%block body %}
    {{v1}}

    <ul>
        {% for item in v2 %}
        <li>{{item}}</li>
        {% endfor %}
    </ul>
    {{v2.1}}

    <ul>
        {% for k,v in v3.items() %}
        <li>{{k}}  {{v}}</li>
        {% endfor %}
    </ul>
    {{v3.k1}}
    {{v3.get('k1')}}

    {{v4}}
    <!--{{v4|safe}}-->

    <h1>{{test(1,19)}}</h1>

    {{sb(1,2)}}

    {{ 1|db(2,3)}}


    {% macro xxxx(name, type='text', value='') %}
        <input type="{{ type }}" name="{{ name }}" value="{{ value }}">
        <input type="{{ type }}" name="{{ name }}" value="{{ value }}">
        <input type="{{ type }}" name="{{ name }}" value="{{ value }}">
        <input type="{{ type }}" name="{{ name }}" value="{{ value }}">
    {% endmacro %}

    {{ xxxx('n1') }}


{%endblock%}

index.html

注意:Markup等价django的mark_safe

**      b、 什么是wsgi?
                           Web服务网管接口,协议。**

     简单介绍:轻量级框架
                  Django:无socket、中间件、路由系统、视图(CBV,FBV)、 模板、O中华VM、cookie、Session、Admin、Form、缓存、                                   功率信号、体系化....
                     Flask:无socket、中间件(扩大)、路由系统、视图(CBV)、第一方模板(jinja贰)、cookie、Session弱爆了

     简单介绍:轻量级框架
                  Django:无socket、中间件、路由系统、视图(CBV,FBV)、 模板、OTiggoM、cookie、Session、Admin、Form、缓存、                                   实信号、种类化....
                     Flask:无socket、中间件(扩大)、路由系统、视图(CBV)、第二方模板(jinja2)、cookie、Session弱爆了

陆、请求和响应

澳门新萄京官方网站 27澳门新萄京官方网站 28

   from flask import Flask
    from flask import request
    from flask import render_template
    from flask import redirect
    from flask import make_response

    app = Flask(__name__)


    @app.route('/login.html', methods=['GET', "POST"])
    def login():

        # 请求相关信息
        # request.method
        # request.args
        # request.form
        # request.values
        # request.cookies
        # request.headers
        # request.path
        # request.full_path
        # request.script_root
        # request.url
        # request.base_url
        # request.url_root
        # request.host_url
        # request.host
        # request.files
        # obj = request.files['the_file_name']
        # obj.save('/var/www/uploads/'   secure_filename(f.filename))

        # 响应相关信息
        # return "字符串"
        # return render_template('html模板路径',**{})
        # return redirect('/index.html')

        # response = make_response(render_template('index.html'))
        # response是flask.wrappers.Response类型
        # response.delete_cookie('key')
        # response.set_cookie('key', 'value')
        # response.headers['X-Something'] = 'A value'
        # return response


        return "内容"

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

View Code

**      c、Flask依赖二个落到实处了WSGI协议的模块:werkzeug**

                   a. 什么是wsgi?
                           Web服务网管接口,协议。

                   a. 什么是wsgi?
                           Web服务网管接口,协议。

七、Session

  除请求对象之外,还应该有1个 session 对象。它同意你在分裂请求间存款和储蓄特定用户的消息。它是在 Cookies 的底蕴上贯彻的,并且对 Cookies 实行密钥署名要接纳会话,你要求安装一个密钥。

  • 设置:session['username'] = 'xxx'

  • 删除:session.pop('username', None)

澳门新萄京官方网站 29澳门新萄京官方网站 30

from flask import Flask, session, redirect, url_for, escape, request

app = Flask(__name__)

@app.route('/')
def index():
    if 'username' in session:
        return 'Logged in as %s' % escape(session['username'])
    return 'You are not logged in'

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        session['username'] = request.form['username']
        return redirect(url_for('index'))
    return '''
        <form action="" method="post">
            <p><input type=text name=username>
            <p><input type=submit value=Login>
        </form>
    '''

@app.route('/logout')
def logout():
    # remove the username from the session if it's there
    session.pop('username', None)
    return redirect(url_for('index'))

# set the secret key.  keep this really secret:
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'

骨干接纳

澳门新萄京官方网站 31澳门新萄京官方网站 32

#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
pip3 install redis
pip3 install flask-session

"""


from flask import Flask, session, redirect
from flask.ext.session import Session


app = Flask(__name__)
app.debug = True
app.secret_key = 'asdfasdfasd'


app.config['SESSION_TYPE'] = 'redis'
from redis import Redis
app.config['SESSION_REDIS'] = Redis(host='192.168.0.94',port='6379')
Session(app)


@app.route('/login')
def login():
    session['username'] = 'alex'
    return redirect('/index')


@app.route('/index')
def index():
    name = session['username']
    return name


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

第三方session

澳门新萄京官方网站 33澳门新萄京官方网站 34

#session.py中用两个类自定义:
import uuid
import json
from flask.sessions import SessionInterface
from flask.sessions import SessionMixin
from itsdangerous import Signer, BadSignature, want_bytes

class MySession(dict, SessionMixin):
    def __init__(self, initial=None, sid=None):
        self.sid = sid
        self.initial = initial
        super(MySession, self).__init__(initial or ())

    def __setitem__(self, key, value):
        super(MySession, self).__setitem__(key, value)

    def __getitem__(self, item):
        return super(MySession, self).__getitem__(item)

    def __delitem__(self, key):
        super(MySession, self).__delitem__(key)




class MySessionInterface(SessionInterface):
    session_class = MySession
    container = {
        # 'asdfasdfasdfas':{'k1':'v1','k2':'v2'}
        # 'asdfasdfasdfas':"{'k1':'v1','k2':'v2'}"
    }

    def __init__(self):
        pass
        # import redis
        # self.redis = redis.Redis()

    def _generate_sid(self):
        return str(uuid.uuid4())

    def _get_signer(self, app):
        if not app.secret_key:
            return None
        return Signer(app.secret_key, salt='flask-session',
                      key_derivation='hmac')

    def open_session(self, app, request):
        """
        程序刚启动时执行,需要返回一个session对象
        """
        sid = request.cookies.get(app.session_cookie_name)
        if not sid:
            # 生成随机字符串,并将随机字符串添加到 session对象中
            sid = self._generate_sid()
            return self.session_class(sid=sid)

        signer = self._get_signer(app)
        try:
            sid_as_bytes = signer.unsign(sid)
            sid = sid_as_bytes.decode()
        except BadSignature:
            sid = self._generate_sid()
            return self.session_class(sid=sid)

        # session保存在redis中
        # val = self.redis.get(sid)
        # session保存在内存中
        val = self.container.get(sid)

        if val is not None:
            try:
                data = json.loads(val)
                return self.session_class(data, sid=sid)
            except:
                return self.session_class(sid=sid)
        return self.session_class(sid=sid)

    def save_session(self, app, session, response):
        """
        程序结束前执行,可以保存session中所有的值
        如:
            保存到resit
            写入到用户cookie
        """
        domain = self.get_cookie_domain(app)
        path = self.get_cookie_path(app)
        httponly = self.get_cookie_httponly(app)
        secure = self.get_cookie_secure(app)
        expires = self.get_expiration_time(app, session)

        val = json.dumps(dict(session))

        # session保存在redis中
        # self.redis.setex(name=session.sid, value=val, time=app.permanent_session_lifetime)
        # session保存在内存中
        self.container.setdefault(session.sid, val)

        session_id = self._get_signer(app).sign(want_bytes(session.sid))

        response.set_cookie(app.session_cookie_name, session_id,
                            expires=expires, httponly=httponly,
                            domain=domain, path=path, secure=secure)





#run.py:
from flask import Flask,request,session
app = Flask(__name__)
app.secret_key = 'sdfsdfsd'
app.session_interface = MySessionInterface()
# app.session_interface
# app.make_null_session()
@app.route('/index')
def index():
    print('网站的所有session',MySessionInterface.container)
    print(session)
    session['k1'] = 'v1'
    session['k2'] = 'v2'
    del session['k1']

    # 在内存中操作字典....
    # session['k1'] = 'v1'
    # session['k2'] = 'v2'
    # del session['k1']

    return "xx"

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

自定义session

补充:

  Flask的session与Django有所不一样,Flask暗中认可服务器不保留session,当用户来访问时若必要用到session则在内部存款和储蓄器中生成字典,字典中存放着相应的键值对,然后经过加盐加密后重返给浏览器,浏览器以cookie的款式保留,访问截至后服务器立刻删除内部存储器中的session。后一次造访时浏览器指引cookie,当中键值对的值就是加密形状的session,经过服务器解密后收获session内容。

  而Django的session则是写入数据库中的,浏览器的cookie只存有sessionid:随机字符串,待下一次作客时由随机字符串相配数据库中的session的键,获得session的值(字典)

 

五、flask

                   b. Flask信赖二个贯彻了WSGI协议的模块:werkzeug

                   b. Flask信赖一个兑现了WSGI协议的模块:werkzeug

八、flash(闪现)

  flash是session的一种新鲜格局,是2个依照Session达成的用来保存数据的集纳,其与平常session的分裂之处:使用贰遍就删除。

澳门新萄京官方网站 35澳门新萄京官方网站 36

from flask import Flask,session,Session,flash,get_flashed_messages,redirect,render_template,request
app = Flask(__name__)
app.secret_key ='sdfsdfsdf'

@app.route('/users')
def users():
    # msg = request.args.get('msg','')
    # msg = session.get('msg')
    # if msg:
    #     del session['msg']

    v = get_flashed_messages()
    print(v)
    msg = ''
    return render_template('users.html',msg=msg)

@app.route('/useradd')
def user_add():
    # 在数据库中添加一条数据
    # 假设添加成功,在跳转到列表页面时,显示添加成功
    # return redirect('/users?msg=添加成功')
    # session['msg'] = '添加成功'

    flash('添加成功')
    return redirect('/users')


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

flash用法

 

       a、 -依赖于wsgi模块:wsgiref,werkzeug,wsgi

flask

flask

九、蓝图

蓝图用于为运用提供目录划分:

微型应用程序:示例

重型应用程序:示例

其他:

  • 蓝图URL前缀:xxx = Blueprint('xxx', __name__,url_prefix='/xxx')
  • 蓝图子域名:xxx = Blueprint('xxx', __name__,subdomain='admin')
    # 使用子域名前提需求给配备SE奥迪Q5VE锐界_NAME: app.config['SERVER_NAME'] = 'helloworld.com:5000'
    # 访问时:admin.helloworld.com:5000/login.html

 实例证实:

澳门新萄京官方网站 37

澳门新萄京官方网站 38澳门新萄京官方网站 39

import fcrm

if __name__ == '__main__':
    fcrm.app.run(port=8001)

manage.py

澳门新萄京官方网站 40澳门新萄京官方网站 41

from flask import Flask
from .views import account
from .views import order

app = Flask(__name__)
print(app.root_path)
app.register_blueprint(account.account)
app.register_blueprint(order.order)

__init__.py

澳门新萄京官方网站 42澳门新萄京官方网站 43

from flask import Blueprint,render_template

account = Blueprint('account',__name__)

@account.route('/login')
def login():
    # return 'Login'
    return render_template('login.html')

account.py

澳门新萄京官方网站 44澳门新萄京官方网站 45

from flask import Blueprint

order = Blueprint('order',__name__)

@order.route('/order')
def login():
    return 'Order'

order.py

 

       b、  -实例化Flask对象

      -依赖于wsgi模块:wsgiref,werkzeug,wsgi

      -依赖于wsgi模块:wsgiref,werkzeug,wsgi

十、请求扩大(Flask中的类似于Django中间件的功能)

澳门新萄京官方网站 46澳门新萄京官方网站 47

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Flask, Request, render_template

app = Flask(__name__, template_folder='templates')
app.debug = True


@app.before_first_request
def before_first_request1():
    print('before_first_request1')


@app.before_first_request
def before_first_request2():
    print('before_first_request2')


@app.before_request
def before_request1():
    Request.nnn = 123
    print('before_request1')


@app.before_request
def before_request2():
    print('before_request2')


@app.after_request
def after_request1(response):
    print('before_request1', response)
    return response


@app.after_request
def after_request2(response):
    print('before_request2', response)
    return response


@app.errorhandler(404)
def page_not_found(error):
    return 'This page does not exist', 404


@app.template_global()
def sb(a1, a2):
    return a1   a2


@app.template_filter()
def db(a1, a2, a3):
    return a1   a2   a3


@app.route('/')
def hello_world():
    return render_template('hello.html')


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

方式一

澳门新萄京官方网站 48澳门新萄京官方网站 49

from flask import Flask,session,Session,flash,get_flashed_messages,redirect,render_template,request
app = Flask(__name__)
app.secret_key ='sdfsdfsdf'

@app.before_request
def process_request1():
    print('process_request1')

@app.after_request
def process_response1(response):
    print('process_response1')
    return response


@app.before_request
def process_request2():
    print('process_request2')

@app.after_request
def process_response2(response):
    print('process_response2')
    return response


@app.route('/index')
def index():
    print('index')
    return 'Index'

@app.route('/order')
def order():
    print('order')
    return 'order'

@app.route('/test')
def test():
    print('test')
    return 'test'

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

方式二

                  -静态文件前缀  /xxx

      -实例化Flask对象

      -实例化Flask对象

拾1、数据库连接池(DButils)

   在Flask中创立拾2线程,在程序运营时若想对数据库进行操作需创建连接。若每便都进展连接的创导,就能够使连接数太多,费时费财富;若直接加锁则不可能帮忙并发。所以那边我们引进数据库连接池来消除难点。

安装

pip3 install dbutils

使用办法:

澳门新萄京官方网站 50澳门新萄京官方网站 51

from flask import Flask
import time
import pymysql
import threading
from DBUtils.PooledDB import PooledDB, SharedDBConnection
POOL = PooledDB(
    creator=pymysql,  # 使用链接数据库的模块
    maxconnections=6,  # 连接池允许的最大连接数,0和None表示不限制连接数
    mincached=2,  # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
    maxcached=5,  # 链接池中最多闲置的链接,0和None不限制
    maxshared=3,  # 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。
    blocking=True,  # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
    maxusage=None,  # 一个链接最多被重复使用的次数,None表示无限制
    setsession=[],  # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
    ping=0,
    # ping MySQL服务端,检查是否服务可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always
    host='127.0.0.1',
    port=3306,
    user='root',
    password='123',
    database='pooldb',
    charset='utf8'
)


app = Flask(__name__)
app.secret_key ='sdfsdfsdf'



@app.route('/index')
def index():
    # 第一步:缺点:每次请求反复创建数据库连接,连接数太多
    # conn = pymysql.connect()
    # cursor = conn.cursor()
    # cursor.execute('select * from tb where id > %s',[5,])
    # result = cursor.fetchall()
    # cursor.close()
    # conn.close()
    # print(result)

    # 第二步:缺点,不能支持并发
    # pymysql.threadsafety
    # with LOCK:
    #     cursor = CONN.cursor()
    #     cursor.execute('select * from tb where id > %s', [5, ])
    #     result = cursor.fetchall()
    #     cursor.close()
    #
    #     print(result)

    # 第三步:基于DBUtils实现数据连接池
    #   - 为每个线程创建一个连接,该线程关闭时,不是真正关闭;本线程再次调用时,还是使用的最开始创建的连接。直到线程终止,数据库连接才关闭。
    #   - 创建一个连接池(10个连接),为所有线程提供连接,使用时来进行获取,使用完毕后,再次放回到连接池。
    #         PS:

    #检测当前正在运行连接数的是否小于最大链接数,如果不小于则:等待或报raise TooManyConnections异常
    # 否则
    # 则优先去初始化时创建的链接中获取链接 SteadyDBConnection。
    # 然后将SteadyDBConnection对象封装到PooledDedicatedDBConnection中并返回。
    # 如果最开始创建的链接没有链接,则去创建一个SteadyDBConnection对象,再封装到PooledDedicatedDBConnection中并返回。
    # 一旦关闭链接后,连接就返回到连接池让后续线程继续使用。
    conn = POOL.connection()
    cursor = conn.cursor()
    cursor.execute('select * from tb1')
    result = cursor.fetchall()
    conn.close()


    return '执行成功'



if __name__ == '__main__':

    app.run()

数据库连接池

扩充:用类的自定义方法解耦数据库连接池的数据库操作

澳门新萄京官方网站 52澳门新萄京官方网站 53

#用类的自定义方法解耦数据库连接池的数据库操作


#创建数据库连接池
import pymysql
import threading
from DBUtils.PooledDB import PooledDB, SharedDBConnection
POOL = PooledDB(
    creator=pymysql,  # 使用链接数据库的模块
    maxconnections=6,  # 连接池允许的最大连接数,0和None表示不限制连接数
    mincached=2,  # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
    maxcached=5,  # 链接池中最多闲置的链接,0和None不限制
    maxshared=3,  # 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。
    blocking=True,  # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
    maxusage=None,  # 一个链接最多被重复使用的次数,None表示无限制
    setsession=[],  # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
    ping=0,
    # ping MySQL服务端,检查是否服务可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always
    host='47.93.4.198',
    port=3306,
    user='root',
    password='123',
    database='s6',
    charset='utf8'
)





#定义用于解耦操作的类
class SQLHelper(object):

    def __init__(self):
        self.conn = None
        self.cursor = None

    def open(self,cursor=pymysql.cursors.DictCursor):
        self.conn = db_pool.POOL.connection()
        self.cursor = self.conn.cursor(cursor=cursor)

    def close(self):
        self.cursor.close()
        self.conn.close()

    def fetchone(self,sql,params):
        cursor = self.cursor
        cursor.execute(sql,params)
        result = cursor.fetchone()

        return result

    def fetchall(self, sql, params):
        cursor = self.cursor
        cursor.execute(sql, params)
        result = cursor.fetchall()
        return result

    def __enter__(self):
        self.open()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()



#调用(可以是在其他文件下,只要引入上述代码所在文件即可)
with SQLHelper() as helper:
    result = helper.fetchone('select * from users where name=%s and pwd = %s',[request.form.get('user'),request.form.get('pwd'),])
    if result:
        #做操作

用类的自定义方法解耦数据库连接池的数据库操作

 

 

                  -静态文件目录

           -静态文件前缀  /xxx

           -静态文件前缀  /xxx

十二、Flask的__call__源码剖判

  Flask实践app.run()时即实践Flask类的__call__方法

澳门新萄京官方网站 54澳门新萄京官方网站 55

import sys
from itertools import chain
from .globals import _request_ctx_stack, _app_ctx_stack



#flaskapp.py:
class Flask(_PackageBoundObject):
    #1、执行__call__方法
    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)
    #2、执行Flask类的wsgi_app方法
    def wsgi_app(self, environ, start_response):
        #2.1、执行Flask类的request_context(environ),最后得到封装了request和session的对象
        ctx = self.request_context(environ)#RequestContext类的对象
        #3、在ctx.py中的RequestContext类中执行push堆栈操作
        ctx.push()
        error = None
        try:
            try:
                #4、执行Flask类的full_dispatch_request方法
                response = self.full_dispatch_request()
            except Exception as e:
                error = e
                response = self.handle_exception(e)
            except:
                error = sys.exc_info()[1]
                raise
            return response(environ, start_response)
        finally:
            if self.should_ignore_error(error):
                error = None
            ctx.auto_pop(error)

    #2.1
    def request_context(self, environ):
        #2.2、实例化了ctx.py中的RequestContext类赋值给2中的ctx,执行其构造方法
        return RequestContext(self, environ)#self=app

    #2.3.1、得到Werkzeug 模块提供的Request
    request_class = Request

    #2.4、封装request
    def create_url_adapter(self, request):
        """Creates a URL adapter for the given request.  The URL adapter
        is created at a point where the request context is not yet set up
        so the request is passed explicitly.

        .. versionadded:: 0.6

        .. versionchanged:: 0.9
           This can now also be called without a request object when the
           URL adapter is created for the application context.
        """
        if request is not None:
            return self.url_map.bind_to_environ(request.environ,
                server_name=self.config['SERVER_NAME'])
        # We need at the very least the server name to be set for this
        # to work.
        if self.config['SERVER_NAME'] is not None:
            return self.url_map.bind(
                self.config['SERVER_NAME'],
                script_name=self.config['APPLICATION_ROOT'] or '/',
                url_scheme=self.config['PREFERRED_URL_SCHEME'])

    #4、
    def full_dispatch_request(self):
       #4.1、执行before_first_request方法,只执行一次
        self.try_trigger_before_first_request_functions()
        try:
            #执行信号
            request_started.send(self)
            #5、执行Flask类的preprocess_request方法,类似Django中间件的装饰器函数
            rv = self.preprocess_request()#rv是装饰器函数的返回值
            if rv is None:#装饰器函数没有返回值,执行视图函数
                # 6、执行Flask类的dispatch_request方法,即视图函数
                rv = self.dispatch_request()
        except Exception as e:
            rv = self.handle_user_exception(e)
           #7、执行Flask类的finalize_request方法,试图函数结束后执行的装饰器
        return self.finalize_request(rv)

    # 5、执行Flask类的preprocess_request方法,类似Django中间件的装饰器函数
    def preprocess_request(self):
        #top读栈中的request
        bp = _request_ctx_stack.top.request.blueprint

        funcs = self.url_value_preprocessors.get(None, ())
        if bp is not None and bp in self.url_value_preprocessors:
            funcs = chain(funcs, self.url_value_preprocessors[bp])
        for func in funcs:
            func(request.endpoint, request.view_args)

        funcs = self.before_request_funcs.get(None, ())
        if bp is not None and bp in self.before_request_funcs:
            funcs = chain(funcs, self.before_request_funcs[bp])
        for func in funcs:
            rv = func()
            if rv is not None:
                return rv

    #6、执行Flask类的dispatch_request方法,即视图函数
    def dispatch_request(self):
        req = _request_ctx_stack.top.request
        if req.routing_exception is not None:
            self.raise_routing_exception(req)
        rule = req.url_rule
        # if we provide automatic options for this URL and the
        # request came with the OPTIONS method, reply automatically
        if getattr(rule, 'provide_automatic_options', False) 
                and req.method == 'OPTIONS':
            return self.make_default_options_response()
        # otherwise dispatch to the handler for that endpoint
        return self.view_functions[rule.endpoint](**req.view_args)

    # 7、执行Flask类的finalize_request方法,试图函数结束后执行的装饰器
    def finalize_request(self, rv, from_error_handler=False):

        response = self.make_response(rv)
        try:
            #8、执行Flask类的process_response方法,处理session
            response = self.process_response(response)
            #信号
            request_finished.send(self, response=response)
        except Exception:
            if not from_error_handler:
                raise
            self.logger.exception('Request finalizing failed with an '
                                  'error while handling an error')
        return response

    # 8、执行Flask类的process_response方法,处理session
    def process_response(self, response):

        ctx = _request_ctx_stack.top
        bp = ctx.request.blueprint
        funcs = ctx._after_request_functions
        if bp is not None and bp in self.after_request_funcs:
            funcs = chain(funcs, reversed(self.after_request_funcs[bp]))
        if None in self.after_request_funcs:
            funcs = chain(funcs, reversed(self.after_request_funcs[None]))
        for handler in funcs:
            response = handler(response)
        if not self.session_interface.is_null_session(ctx.session):
            self.save_session(ctx.session, response)
        return response







#ctx.py:
class RequestContext(object):
    #2.2、
    def __init__(self, app, environ, request=None):
        #self=ctx,app=app
        self.app = app
        # 2.3.1、如果没有request的话,执行Flask类下的request_class静态字段
        if request is None:
            request = app.request_class(environ)
        #2.3.2、有request
        self.request = request
        #2.4、执行Flask类下的create_url_adapter方法封装request
        self.url_adapter = app.create_url_adapter(self.request)
        #2.5、默认flashes和session为None
        self.flashes = None
        self.session = None

    #3、堆栈操作
    def push(self):
        # _request_ctx_stack=LocalStack(),由文件导入过来,是一个字典
        top = _request_ctx_stack.top#top是读栈
        if top is not None and top.preserved:
            top.pop(top._preserved_exc)
        #_app_ctx_stack = LocalStack()
        app_ctx = _app_ctx_stack.top
        if app_ctx is None or app_ctx.app != self.app:
            app_ctx = self.app.app_context()
            app_ctx.push()
            self._implicit_app_ctx_stack.append(app_ctx)
        else:
            self._implicit_app_ctx_stack.append(None)

        if hasattr(sys, 'exc_clear'):
            sys.exc_clear()
        #3.1 堆栈操作
        _request_ctx_stack.push(self)
        #查看session,如果没有的话赋予NullSession
        self.session = self.app.open_session(self.request)
        if self.session is None:
            self.session = self.app.make_null_session()



#global.py:
from functools import partial
from werkzeug.local import LocalStack, LocalProxy
_request_ctx_stack = LocalStack()
_app_ctx_stack = LocalStack()
current_app = LocalProxy(_find_app)
request = LocalProxy(partial(_lookup_req_object, 'request'))
session = LocalProxy(partial(_lookup_req_object, 'session'))
g = LocalProxy(partial(_lookup_app_object, 'g'))






#local.py:
class LocalStack(object):


    def __init__(self):
        #_request_ctx_stack._local=self._local=__storage__: {线程或协程唯一标识: {"stack": [request]}, }
        self._local = Local()#形成牛逼的字典

    def __release_local__(self):
        self._local.__release_local__()

    def _get__ident_func__(self):
        return self._local.__ident_func__

    def _set__ident_func__(self, value):
        object.__setattr__(self._local, '__ident_func__', value)
    __ident_func__ = property(_get__ident_func__, _set__ident_func__)
    del _get__ident_func__, _set__ident_func__

    def __call__(self):
        def _lookup():
            rv = self.top
            if rv is None:
                raise RuntimeError('object unbound')
            return rv
        return LocalProxy(_lookup)
    #3.1、堆栈操作
    def push(self, obj):
        """Pushes a new item to the stack"""
        rv = getattr(self._local, 'stack', None)#找牛逼的字典中有没有叫stack的键,默认为None
        if rv is None:#如果是None的话,在牛逼的字典中创建"stack":[]
            self._local.stack = rv = []
        rv.append(obj)#将obj放入[],真正的堆栈操作
        return rv

    def pop(self):
        """Removes the topmost item from the stack, will return the
        old value or `None` if the stack was already empty.
        """
        stack = getattr(self._local, 'stack', None)
        if stack is None:
            return None
        elif len(stack) == 1:
            release_local(self._local)
            return stack[-1]
        else:
            return stack.pop()

    @property
    def top(self):
        """The topmost item on the stack.  If the stack is empty,
        `None` is returned.
        """
        try:
            return self._local.stack[-1]
        except (AttributeError, IndexError):
            return None


class Local(object):
    __slots__ = ('__storage__', '__ident_func__')

    def __init__(self):
        #最后得到__storage__:{线程或协程唯一标识:{"stack":[request]},}.赋值给LocalStack()._local,即_request_ctx_stack
        object.__setattr__(self, '__storage__', {})
        object.__setattr__(self, '__ident_func__', get_ident)

    def __iter__(self):
        return iter(self.__storage__.items())

    def __call__(self, proxy):
        """Create a proxy for a name."""
        return LocalProxy(self, proxy)

    def __release_local__(self):
        self.__storage__.pop(self.__ident_func__(), None)

    def __getattr__(self, name):
        try:
            return self.__storage__[self.__ident_func__()][name]
        except KeyError:
            raise AttributeError(name)

    def __setattr__(self, name, value):
        ident = self.__ident_func__()
        storage = self.__storage__
        try:
            storage[ident][name] = value
        except KeyError:
            storage[ident] = {name: value}

    def __delattr__(self, name):
        try:
            del self.__storage__[self.__ident_func__()][name]
        except KeyError:
            raise AttributeError(name)

flask实施app.run()时源码流程

 

 

                  -模板路线

           -静态文件目录

           -静态文件目录

十三、信号 blinker

安装  pip3 install blinker

  Flask有十个放置频限信号,时域信号是什么吗,是请求试行时会自动推行的一部分措施,未有重返值。随机信号在源码中靠send触发。

嵌入非非确定性信号:

澳门新萄京官方网站 56澳门新萄京官方网站 57

2. request_started = _signals.signal('request-started')                # 请求到来前执行
5. request_finished = _signals.signal('request-finished')              # 请求结束后执行

3. before_render_template = _signals.signal('before-render-template')  # 模板渲染前执行
4. template_rendered = _signals.signal('template-rendered')            # 模板渲染后执行

2/3/4/5或不执行 got_request_exception = _signals.signal('got-request-exception')    # 请求执行出现异常时执行

6. request_tearing_down = _signals.signal('request-tearing-down')      # 请求执行完毕后自动执行(无论成功与否)
7. appcontext_tearing_down = _signals.signal('appcontext-tearing-down')# 请求上下文执行完毕后自动执行(无论成功与否)


1. appcontext_pushed = _signals.signal('appcontext-pushed')            # 请求app上下文push时执行

8. appcontext_popped = _signals.signal('appcontext-popped')            # 请求上下文pop时执行

最后.message_flashed = _signals.signal('message-flashed')                   # 调用flask在其中添加数据时,自动触发

放置十二个数字信号

  信号用于做如何?

    首借使用于降落代码之间的耦合

  特殊的装饰器和功率信号有何差距?  

    装饰器重回值有意义

自定义功率信号:

  效率:发送短信,邮件,微信     

澳门新萄京官方网站 58澳门新萄京官方网站 59

from flask import Flask,flash
from flask.signals import _signals
app = Flask(__name__)
mysignal = _signals.signal('mysignal')#实质上是一个列表


# 定义函数
def fun1(*args,**kwargs):
    print('函数一',args,kwargs)

# 定义函数
def fun2(*args,**kwargs):
    print('函数二',args,kwargs)

# 将函数注册到request_started信号中: 添加到这个列表
mysignal.connect(fun1)
mysignal.connect(fun2)




@app.route('/index')
def index():
    # 触发这个信号:执行注册到列表中的所有函数
    # 自定义信号的作用:发送短信,邮件,微信     
    mysignal.send(sender='xxx',a1=123,a2=456)
    return "xx"

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

自定义能量信号

 

        c、 增加路由关系      

           -模板路线

           -模板路径

十四、Flask插件

  • flask-script
  • wtforms
  • SQLAlchemy
  • 等...    

 

                  -将 Rule(url和视图函数)增多到Flask对象的url_map字段中

     加多路由关系

     增多路由关系

拾5、项目须知

  • freeze和pipreqs
  • Flask项目示范目录

 

 

 

 

 

                  -二种增多路由的办法

           -将 Rule(url和视图函数)增加到Flask对象的url_map字段中

           -将 Rule(url和视图函数)增添到Flask对象的url_map字段中

        d、request

           -三种增加路由的方法

           -二种加多路由的点子

                 -request.form

     request

     request

                 -request.args 

          -request.form

          -request.form

6、基本采取

          -request.args 

          -request.args 

from flask import Flask

# 实例化Flask对象
app = Flask(__name__)

# 生成路由关系,并把关系保存到某个地方,app对象的 url_map字段中
@app.route('/xxxx')  # @decorator
def index():
    return "Index"

# def index():
#     return "Index"
# app.add_url_rule('/xxx', "n1", index)

if __name__ == '__main__':
    # 启动程序,监听用户请求
    # 一旦请求到来,执行 app.__call__方法
    # 封装用户请求
    # 进行路由匹配
    app.run()

四.着力使用:

四.核心使用:

     a、保留session的多寡存到了浏览器上,
        - 优点:减轻了服务端的压力
        - 缺点:不安全

from flask import Flask

# 实例化Flask对象
app = Flask(__name__)

# 生成路由关系,并把关系保存到某个地方,app对象的 url_map字段中
@app.route('/xxxx')  # @decorator
def index():
    return "Index"

# def index():
#     return "Index"
# app.add_url_rule('/xxx', "n1", index)

if __name__ == '__main__':
    # 启动程序,监听用户请求
    # 一旦请求到来,执行 app.__call__方法
    # 封装用户请求
    # 进行路由匹配
    app.run()
from flask import Flask

# 实例化Flask对象
app = Flask(__name__)

# 生成路由关系,并把关系保存到某个地方,app对象的 url_map字段中
@app.route('/xxxx')  # @decorator
def index():
    return "Index"

# def index():
#     return "Index"
# app.add_url_rule('/xxx', "n1", index)

if __name__ == '__main__':
    # 启动程序,监听用户请求
    # 一旦请求到来,执行 app.__call__方法
    # 封装用户请求
    # 进行路由匹配
    app.run()

     b、路由系统:  

练习:

练习:

  • @app.route('/post/<path:path>')
  • @app.route('/login', methods=['GET', 'POST'])
from flask import Flask,render_template,request,redirect,session
app = Flask(__name__)
app.secret_key = "sdsfdsgdfgdfgfh"

def wrapper(func):
    def inner(*args,**kwargs):
        if not session.get("user_info"):
            return redirect("/login")
        ret = func(*args,**kwargs)
        return ret
    return inner

@app.route("/login",methods=["GET","POST"])
def login():
    if request.method=="GET":
        return render_template("login.html")
    else:
        # print(request.values)   #这个里面什么都有,相当于body
        username = request.form.get("username")
        password = request.form.get("password")
        if username=="haiyan" and password=="123":
            session["user_info"] = username
            # session.pop("user_info")  #删除session
            return redirect("/index")
        else:
            # return render_template("login.html",**{"msg":"用户名或密码错误"})
            return render_template("login.html",msg="用户名或者密码错误")

@app.route("/index",methods=["GET","POST"])
@wrapper
def index():
    # if not session.get("user_info"):
    #     return redirect("/login")
    return render_template("index.html")


if __name__ == '__main__':
    app.run(debug=True)
from flask import Flask,render_template,request,redirect,session
app = Flask(__name__)
app.secret_key = "sdsfdsgdfgdfgfh"

def wrapper(func):
    def inner(*args,**kwargs):
        if not session.get("user_info"):
            return redirect("/login")
        ret = func(*args,**kwargs)
        return ret
    return inner

@app.route("/login",methods=["GET","POST"])
def login():
    if request.method=="GET":
        return render_template("login.html")
    else:
        # print(request.values)   #这个里面什么都有,相当于body
        username = request.form.get("username")
        password = request.form.get("password")
        if username=="haiyan" and password=="123":
            session["user_info"] = username
            # session.pop("user_info")  #删除session
            return redirect("/index")
        else:
            # return render_template("login.html",**{"msg":"用户名或密码错误"})
            return render_template("login.html",msg="用户名或者密码错误")

@app.route("/index",methods=["GET","POST"])
@wrapper
def index():
    # if not session.get("user_info"):
    #     return redirect("/login")
    return render_template("index.html")


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

保存session的多寡存到了浏览器上,
  - 优点:缓慢解决了服务端的下压力
  - 缺点:不安全

封存session的数额存到了浏览器上,
  - 优点:缓慢解决了服务端的下压力
  - 缺点:不安全

  • @app.route('/user/<username>')
  • @app.route('/post/<int:post_id>')
  • @app.route('/post/<float:post_id>')

伍.路由系统:

5.路由系统:

七、路由系统**

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

**     a、  -可传唱参数**     **

            @app.route('/user/<username>')

  • @app.route('/user/<username>')
  • @app.route('/post/<int:post_id>')
  • @app.route('/post/<float:post_id>')
  • @app.route('/user/<username>')
  • @app.route('/post/<int:post_id>')
  • @app.route('/post/<float:post_id>')

            @qpp.route('/post/<int:post_id>',methods=['GET','POST'],endpoint='fff')

    路由系统

    路由系统

     b、反向生成U奥德赛L:url_for**

      -可传唱参数

      -可传唱参数

     c、扩大Flask的路由系统,让它扶助正则:**

           @app.route('/user/<username>')

           @app.route('/user/<username>')

from flask import Flask,url_for

                app = Flask(__name__)

                # 定义转换的类
                from werkzeug.routing import BaseConverter
                class RegexConverter(BaseConverter):
                    """
                    自定义URL匹配正则表达式
                    """

                    def __init__(self, map, regex):
                        super(RegexConverter, self).__init__(map)
                        self.regex = regex

                    def to_python(self, value):
                        """
                        路由匹配时,匹配成功后传递给视图函数中参数的值
                        :param value: 
                        :return: 
                        """
                        return int(value)

                    def to_url(self, value):
                        """
                        使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数
                        :param value: 
                        :return: 
                        """
                        val = super(RegexConverter, self).to_url(value)
                        return val

                # 添加到converts中
                app.url_map.converters['xxx'] = RegexConverter

                # 进行使用
                @app.route('/index/<xxx("d "):nid>',endpoint='xx')
                def index(nid):
                    url_for('xx',nid=123)
                    return "Index"

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

           @qpp.route('/post/<int:post_id>',methods=['GET','POST'],endpoint='fff')

           @qpp.route('/post/<int:post_id>',methods=['GET','POST'],endpoint='fff')

捌、请求响应

     -反向生成U汉兰达L:url_for

     -反向生成U昂科威L:url_for

from flask import Flask
    from flask import request
    from flask import render_template
    from flask import redirect
    from flask import make_response

    app = Flask(__name__)


    @app.route('/login.html', methods=['GET', "POST"])
    def login():

        # 请求相关信息
        # request.method
        # request.args
        # request.form
        # request.values
        # request.cookies
        # request.headers
        # request.path
        # request.full_path
        # request.script_root
        # request.url
        # request.base_url
        # request.url_root
        # request.host_url
        # request.host
        # request.files
        # obj = request.files['the_file_name']
        # obj.save('/var/www/uploads/'   secure_filename(f.filename))

        # 响应相关信息
        # return "字符串"
        # return render_template('html模板路径',**{})
        # return redirect('/index.html')

        # response = make_response(render_template('index.html'))
        # response是flask.wrappers.Response类型
        # response.delete_cookie('key')
        # response.set_cookie('key', 'value')
        # response.headers['X-Something'] = 'A value'
        # return response


        return "内容"

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

     -重定向

     -重定向

    a、在django中用make_safe而在Flask中用make_response

     -扩展Flask的路由系统,让它帮衬正则:

     -扩大Flask的路由系统,让它帮助正则:

九、模板语言   **

from flask import Flask,url_for

                app = Flask(__name__)

                # 定义转换的类
                from werkzeug.routing import BaseConverter
                class RegexConverter(BaseConverter):
                    """
                    自定义URL匹配正则表达式
                    """

                    def __init__(self, map, regex):
                        super(RegexConverter, self).__init__(map)
                        self.regex = regex

                    def to_python(self, value):
                        """
                        路由匹配时,匹配成功后传递给视图函数中参数的值
                        :param value: 
                        :return: 
                        """
                        return int(value)

                    def to_url(self, value):
                        """
                        使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数
                        :param value: 
                        :return: 
                        """
                        val = super(RegexConverter, self).to_url(value)
                        return val

                # 添加到converts中
                app.url_map.converters['xxx'] = RegexConverter

                # 进行使用
                @app.route('/index/<xxx("d "):nid>',endpoint='xx')
                def index(nid):
                    url_for('xx',nid=123)
                    return "Index"

                if __name__ == '__main__':
                    app.run()
from flask import Flask,url_for

                app = Flask(__name__)

                # 定义转换的类
                from werkzeug.routing import BaseConverter
                class RegexConverter(BaseConverter):
                    """
                    自定义URL匹配正则表达式
                    """

                    def __init__(self, map, regex):
                        super(RegexConverter, self).__init__(map)
                        self.regex = regex

                    def to_python(self, value):
                        """
                        路由匹配时,匹配成功后传递给视图函数中参数的值
                        :param value: 
                        :return: 
                        """
                        return int(value)

                    def to_url(self, value):
                        """
                        使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数
                        :param value: 
                        :return: 
                        """
                        val = super(RegexConverter, self).to_url(value)
                        return val

                # 添加到converts中
                app.url_map.converters['xxx'] = RegexConverter

                # 进行使用
                @app.route('/index/<xxx("d "):nid>',endpoint='xx')
                def index(nid):
                    url_for('xx',nid=123)
                    return "Index"

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

     a、模板的使用

6.视图函数

陆.视图函数

               Flask使用的是Jinja贰模板,所以其语法和Django无差距

Django:
            /index/    func

            /index/    IndexClass.as_view()

        Flask:
            FBV:
                @app.route('/index',endpoint='xx')
                def index(nid):
                    url_for('xx',nid=123)
                    return "Index"



                def index(nid):
                    url_for('xx',nid=123)
                    return "Index"

                app.add_url_rule('/index',index)

            CBV:
                def auth(func):
                    def inner(*args, **kwargs):
                        result = func(*args, **kwargs)
                        return result
                    return inner

                class IndexView(views.MethodView):
                    # methods = ['POST']

                    decorators = [auth,]       #静态字段

                    def get(self):
                        v = url_for('index')
                        print(v)
                        return "GET"

                    def post(self):
                        return "GET"

                app.add_url_rule('/index', view_func=IndexView.as_view(name='index'))

                if __name__ == '__main__':
                    app.run()
Django:
            /index/    func

            /index/    IndexClass.as_view()

        Flask:
            FBV:
                @app.route('/index',endpoint='xx')
                def index(nid):
                    url_for('xx',nid=123)
                    return "Index"



                def index(nid):
                    url_for('xx',nid=123)
                    return "Index"

                app.add_url_rule('/index',index)

            CBV:
                def auth(func):
                    def inner(*args, **kwargs):
                        result = func(*args, **kwargs)
                        return result
                    return inner

                class IndexView(views.MethodView):
                    # methods = ['POST']

                    decorators = [auth,]       #静态字段

                    def get(self):
                        v = url_for('index')
                        print(v)
                        return "GET"

                    def post(self):
                        return "GET"

                app.add_url_rule('/index', view_func=IndexView.as_view(name='index'))

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

     b、自定义模板方法

六.请求响应

六.伸手响应

               Flask中自定义模板方法的措施和Bottle相似,创造一个函数并通过参数的款式传播render_template,

 

 

十、session 

澳门新萄京官方网站 60澳门新萄京官方网站 61

澳门新萄京官方网站 62澳门新萄京官方网站 63

      a、 -session是不是还应该有此外事办公室法?

from flask import Flask
    from flask import request
    from flask import render_template
    from flask import redirect
    from flask import make_response

    app = Flask(__name__)


    @app.route('/login.html', methods=['GET', "POST"])
    def login():

        # 请求相关信息
        # request.method
        # request.args
        # request.form
        # request.values
        # request.cookies
        # request.headers
        # request.path
        # request.full_path
        # request.script_root
        # request.url
        # request.base_url
        # request.url_root
        # request.host_url
        # request.host
        # request.files
        # obj = request.files['the_file_name']
        # obj.save('/var/www/uploads/'   secure_filename(f.filename))

        # 响应相关信息
        # return "字符串"
        # return render_template('html模板路径',**{})
        # return redirect('/index.html')

        # response = make_response(render_template('index.html'))
        # response是flask.wrappers.Response类型
        # response.delete_cookie('key')
        # response.set_cookie('key', 'value')
        # response.headers['X-Something'] = 'A value'
        # return response


        return "内容"

    if __name__ == '__main__':
        app.run()
from flask import Flask
    from flask import request
    from flask import render_template
    from flask import redirect
    from flask import make_response

    app = Flask(__name__)


    @app.route('/login.html', methods=['GET', "POST"])
    def login():

        # 请求相关信息
        # request.method
        # request.args
        # request.form
        # request.values
        # request.cookies
        # request.headers
        # request.path
        # request.full_path
        # request.script_root
        # request.url
        # request.base_url
        # request.url_root
        # request.host_url
        # request.host
        # request.files
        # obj = request.files['the_file_name']
        # obj.save('/var/www/uploads/'   secure_filename(f.filename))

        # 响应相关信息
        # return "字符串"
        # return render_template('html模板路径',**{})
        # return redirect('/index.html')

        # response = make_response(render_template('index.html'))
        # response是flask.wrappers.Response类型
        # response.delete_cookie('key')
        # response.set_cookie('key', 'value')
        # response.headers['X-Something'] = 'A value'
        # return response


        return "内容"

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

                     -它与字典方法1致

请求响应

呼吁响应

      b、  -session超时时间怎么设置:**

 

 

app.config['SESSION_COOKIE_NAME'] = 'session_lvning'
            """
            'SESSION_COOKIE_NAME':                  'session',
            'SESSION_COOKIE_DOMAIN':                None,
            'SESSION_COOKIE_PATH':                  None,
            'SESSION_COOKIE_HTTPONLY':              True,
            'SESSION_COOKIE_SECURE':                False,
            'SESSION_REFRESH_EACH_REQUEST':         True,
            'PERMANENT_SESSION_LIFETIME':           timedelta(days=31)

    - from urllib.parse import urlencode,quote,unquote
    - make_response

    - from urllib.parse import urlencode,quote,unquote
    - make_response

     c、除请求对象之外,还或许有三个 session 对象。它同意你在差别请求间存款和储蓄特定用户的新闻。它是在 Cookies 的功底上实现的,并且对 Cookies 实行密钥签字要利用会话,你必要安装三个密钥。

在django中用make_safe而在Flask中用make_response

在django中用make_safe而在Flask中用make_response

     d、

 

 

  • 设置:session['username'] = 'xxx'

  • 删除:session.pop('username', None)

from flask import Flask,url_for,request,redirect,render_template,jsonify,make_response
from urllib.parse import urlencode,quote,unquote
app = Flask(__name__)

@app.route('/index',endpoint='xx')
def index():
    from werkzeug.datastructures import ImmutableMultiDict
    # get_data = request.args
    # get_dict = get_data.to_dict()
    # get_dict['xx'] = '18'
    # url = urlencode(get_dict)
    # print(url)

    # print(request.query_string)
    # print(request.args)

    # val = "把几个"
    # print(unquote(val))
    #
    # return "Index"

    # return "Index"
    # return redirect()
    # return render_template()
    # return jsonify(name='alex',age='18')

    response = make_response('xxxxx')
    response.headers['xxx'] = '123123'
    return response


if __name__ == '__main__':
    # app.__call__
    app.run()
from flask import Flask,url_for,request,redirect,render_template,jsonify,make_response
from urllib.parse import urlencode,quote,unquote
app = Flask(__name__)

@app.route('/index',endpoint='xx')
def index():
    from werkzeug.datastructures import ImmutableMultiDict
    # get_data = request.args
    # get_dict = get_data.to_dict()
    # get_dict['xx'] = '18'
    # url = urlencode(get_dict)
    # print(url)

    # print(request.query_string)
    # print(request.args)

    # val = "把几个"
    # print(unquote(val))
    #
    # return "Index"

    # return "Index"
    # return redirect()
    # return render_template()
    # return jsonify(name='alex',age='18')

    response = make_response('xxxxx')
    response.headers['xxx'] = '123123'
    return response


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

十一、闪现(flash)**

 

 

     a、session从在在服务端的多少个字典中,session保存的多少取三回,它依旧会有。而flash是依照session创立的,flash协理在里面放值,只要在内部取值它就能够未有。闪现正是**

7.模板语言   

七.模板语言   

     b、在session的基础上,把它的值真实的放在session上,当去它的时候不但把它的值取走,还把session的东西去掉。

     a、模板的应用

     a、模板的采纳

十二、蓝图**

               Flask使用的是Jinja二模板,所以其语法和Django一点差别也没有

               Flask使用的是Jinja二模板,所以其语法和Django无异

     a、蓝图用于为利用提供目录划分**

     b、自定义模板方法

     b、自定义模板方法

  • 蓝图URL前缀:xxx = Blueprint('account', __name__,url_prefix='/xxx')
  • 蓝图子域名:xxx = Blueprint('account', __name__,subdomain='admin')
    # 前提要求给配备SECRUISERVE昂Cora_NAME: app.config['SERVER_NAME'] = 'wupeiqi.com:5000'
    # 访问时:admin.wupeiqi.com:5000/login.html

               Flask中自定义模板方法的章程和Bottle相似,创造1个函数并经过参数的款型传播render_template,如:

               Flask中自定义模板方法的法子和Bottle相似,成立一个函数并透过参数的款型传播render_template,如:

十三、DBUtils**

澳门新萄京官方网站 64澳门新萄京官方网站 65

澳门新萄京官方网站 66澳门新萄京官方网站 67

      a、DBUtils是Python的一个用以落到实处数据库连接池的模块。**

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <h1>自定义函数</h1>
    {{ww()|safe}}

</body>
</html>

html
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <h1>自定义函数</h1>
    {{ww()|safe}}

</body>
</html>

html

      b、连接池的两种情势:**

html

html

            (一)、第三种格局:

澳门新萄京官方网站 68澳门新萄京官方网站 69

澳门新萄京官方网站 70澳门新萄京官方网站 71

                                 它的宿疾:每三回呼吁反复创立数据库的链接,链接的次数太多

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Flask,render_template
app = Flask(__name__)


def wupeiqi():
    return '<h1>Wupeiqi</h1>'

@app.route('/login', methods=['GET', 'POST'])
def login():
    return render_template('login.html', ww=wupeiqi)

app.run()

run.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Flask,render_template
app = Flask(__name__)


def wupeiqi():
    return '<h1>Wupeiqi</h1>'

@app.route('/login', methods=['GET', 'POST'])
def login():
    return render_template('login.html', ww=wupeiqi)

app.run()

run.py

             (二)、第二种方式:

run

run

                                 它的欠缺:无法支撑并发

澳门新萄京官方网站 72澳门新萄京官方网站 73

澳门新萄京官方网站 74澳门新萄京官方网站 75

              (三)、第二种情势:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>


    {% macro input(name, type='text', value='') %}
        <input type="{{ type }}" name="{{ name }}" value="{{ value }}">
    {% endmacro %}

    {{ input('n1') }}

    {% include 'tp.html' %}

    <h1>asdf{{ v.k1}}</h1>
</body>
</html>

其他
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>


    {% macro input(name, type='text', value='') %}
        <input type="{{ type }}" name="{{ name }}" value="{{ value }}">
    {% endmacro %}

    {{ input('n1') }}

    {% include 'tp.html' %}

    <h1>asdf{{ v.k1}}</h1>
</body>
</html>

其他

                                它是依靠DBUtils达成数据库连接池

其他

其他

                                        -为种种线程创设2个链接,该线程关闭时,不是确实的闭馆,本线程再次调用时,如故使用的最初阶的创制的链接,知道线程终止,数据库链接才关闭

8.session

8.session

                                       -成立三个连接池(十二个链接),为有着线程提供链接,使用时来举办获取,使用完成时,再一次放回到连接池。

     -session是或不是还会有其余形式?

     -session是还是不是还恐怕有别的办法?

       c、DBUtils的应用:**

             -它与字典方法一致

             -它与字典方法一样

import time
import pymysql
import threading
from DBUtils.PooledDB import PooledDB, SharedDBConnection
POOL = PooledDB(
    creator=pymysql,  # 使用链接数据库的模块
    maxconnections=6,  # 连接池允许的最大连接数,0和None表示不限制连接数
    mincached=2,  # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
    maxcached=5,  # 链接池中最多闲置的链接,0和None不限制
    maxshared=3,  # 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。
    blocking=True,  # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
    maxusage=None,  # 一个链接最多被重复使用的次数,None表示无限制
    setsession=[],  # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
    ping=0,
    # ping MySQL服务端,检查是否服务可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always
    host='127.0.0.1',
    port=3306,
    user='root',
    password='123',
    database='pooldb',
    charset='utf8'
)

    -session超时时间怎么设置:

    -session超时时间怎么着设置:

十四、session

app.config['SESSION_COOKIE_NAME'] = 'session_lvning'
            """
            'SESSION_COOKIE_NAME':                  'session',
            'SESSION_COOKIE_DOMAIN':                None,
            'SESSION_COOKIE_PATH':                  None,
            'SESSION_COOKIE_HTTPONLY':              True,
            'SESSION_COOKIE_SECURE':                False,
            'SESSION_REFRESH_EACH_REQUEST':         True,
            'PERMANENT_SESSION_LIFETIME':           timedelta(days=31)
app.config['SESSION_COOKIE_NAME'] = 'session_lvning'
            """
            'SESSION_COOKIE_NAME':                  'session',
            'SESSION_COOKIE_DOMAIN':                None,
            'SESSION_COOKIE_PATH':                  None,
            'SESSION_COOKIE_HTTPONLY':              True,
            'SESSION_COOKIE_SECURE':                False,
            'SESSION_REFRESH_EACH_REQUEST':         True,
            'PERMANENT_SESSION_LIFETIME':           timedelta(days=31)

      a、 session和cookie的原理和界别:

除请求对象之外,还应该有二个session 对象。它同意你在区别请求间存款和储蓄特定用户的音信。它是在 Cookies 的功底上落到实处的,并且对 Cookies 进行密钥具名要使用会话,你供给设置1个密钥。

除请求对象之外,还也是有一个session 对象。它同意你在差别请求间存款和储蓄特定用户的音讯。它是在 Cookies 的基本功上落实的,并且对 Cookies 举行密钥具名要运用会话,你须要安装五个密钥。

               cookie是保留在浏览器上的键值对
               session是存在服务端的键值对(服务端的session便是三个大字典,字典中是随机字符串)(session与request原理同样)(session原理跟上下文也可能有关联)

  • 设置:session['username'] = 'xxx'

  • 删除:session.pop('username', None)

  • 设置:session['username'] = 'xxx'

  • 删除:session.pop('username', None)

               session依赖于cookie存在**

澳门新萄京官方网站 76澳门新萄京官方网站 77

澳门新萄京官方网站 78澳门新萄京官方网站 79

**      b、  session流程**      **

from flask import Flask, session, redirect, url_for, escape, request

app = Flask(__name__)

@app.route('/')
def index():
    if 'username' in session:
        return 'Logged in as %s' % escape(session['username'])
    return 'You are not logged in'

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        session['username'] = request.form['username']
        return redirect(url_for('index'))
    return '''
        <form action="" method="post">
            <p><input type=text name=username>
            <p><input type=submit value=Login>
        </form>
    '''

@app.route('/logout')
def logout():
    # remove the username from the session if it's there
    session.pop('username', None)
    return redirect(url_for('index'))

# set the secret key.  keep this really secret:
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
from flask import Flask, session, redirect, url_for, escape, request

app = Flask(__name__)

@app.route('/')
def index():
    if 'username' in session:
        return 'Logged in as %s' % escape(session['username'])
    return 'You are not logged in'

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        session['username'] = request.form['username']
        return redirect(url_for('index'))
    return '''
        <form action="" method="post">
            <p><input type=text name=username>
            <p><input type=submit value=Login>
        </form>
    '''

@app.route('/logout')
def logout():
    # remove the username from the session if it's there
    session.pop('username', None)
    return redirect(url_for('index'))

# set the secret key.  keep this really secret:
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
当请求第一次进来,生成随机字符串
                  -发给用户cookie
                  -保存到session字典中时
                  它调用stark将随机字符串和对应的值放到local
                视图函数
                 -使用时导入用top(它拿的是session)
                     session=LocalProxy(partile(_lookup_req_object,'session '))
               请求处理完毕:
                     内存处理完毕后,将session做持久化(session存到数据库,存到Redis,存到加密的cookie中)

基本采取

主题使用

十五、session源码解析

澳门新萄京官方网站 80澳门新萄京官方网站 81

澳门新萄京官方网站 82澳门新萄京官方网站 83

     a、先执行Flask的__call__方法 ,调用出来wsgi_app,它先做request的上下文做完,请求刚进来到push中,它先拍卖request将请求相关的数目,然后增添到了local中,

pip3 install Flask-Session

        run.py
            from flask import Flask
            from flask import session
            from pro_flask.utils.session import MySessionInterface
            app = Flask(__name__)

            app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
            app.session_interface = MySessionInterface()

            @app.route('/login.html', methods=['GET', "POST"])
            def login():
                print(session)
                session['user1'] = 'alex'
                session['user2'] = 'alex'
                del session['user2']

                return "内容"

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

        session.py
            #!/usr/bin/env python
            # -*- coding:utf-8 -*-
            import uuid
            import json
            from flask.sessions import SessionInterface
            from flask.sessions import SessionMixin
            from itsdangerous import Signer, BadSignature, want_bytes


            class MySession(dict, SessionMixin):
                def __init__(self, initial=None, sid=None):
                    self.sid = sid
                    self.initial = initial
                    super(MySession, self).__init__(initial or ())


                def __setitem__(self, key, value):
                    super(MySession, self).__setitem__(key, value)

                def __getitem__(self, item):
                    return super(MySession, self).__getitem__(item)

                def __delitem__(self, key):
                    super(MySession, self).__delitem__(key)



            class MySessionInterface(SessionInterface):
                session_class = MySession
                container = {}

                def __init__(self):
                    import redis
                    self.redis = redis.Redis()

                def _generate_sid(self):
                    return str(uuid.uuid4())

                def _get_signer(self, app):
                    if not app.secret_key:
                        return None
                    return Signer(app.secret_key, salt='flask-session',
                                  key_derivation='hmac')

                def open_session(self, app, request):
                    """
                    程序刚启动时执行,需要返回一个session对象
                    """
                    sid = request.cookies.get(app.session_cookie_name)
                    if not sid:
                        sid = self._generate_sid()
                        return self.session_class(sid=sid)

                    signer = self._get_signer(app)
                    try:
                        sid_as_bytes = signer.unsign(sid)
                        sid = sid_as_bytes.decode()
                    except BadSignature:
                        sid = self._generate_sid()
                        return self.session_class(sid=sid)

                    # session保存在redis中
                    # val = self.redis.get(sid)
                    # session保存在内存中
                    val = self.container.get(sid)

                    if val is not None:
                        try:
                            data = json.loads(val)
                            return self.session_class(data, sid=sid)
                        except:
                            return self.session_class(sid=sid)
                    return self.session_class(sid=sid)

                def save_session(self, app, session, response):
                    """
                    程序结束前执行,可以保存session中所有的值
                    如:
                        保存到resit
                        写入到用户cookie
                    """
                    domain = self.get_cookie_domain(app)
                    path = self.get_cookie_path(app)
                    httponly = self.get_cookie_httponly(app)
                    secure = self.get_cookie_secure(app)
                    expires = self.get_expiration_time(app, session)

                    val = json.dumps(dict(session))

                    # session保存在redis中
                    # self.redis.setex(name=session.sid, value=val, time=app.permanent_session_lifetime)
                    # session保存在内存中
                    self.container.setdefault(session.sid, val)

                    session_id = self._get_signer(app).sign(want_bytes(session.sid))

                    response.set_cookie(app.session_cookie_name, session_id,
                                        expires=expires, httponly=httponly,
                                        domain=domain, path=path, secure=secure)

自定义Session
pip3 install Flask-Session

        run.py
            from flask import Flask
            from flask import session
            from pro_flask.utils.session import MySessionInterface
            app = Flask(__name__)

            app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
            app.session_interface = MySessionInterface()

            @app.route('/login.html', methods=['GET', "POST"])
            def login():
                print(session)
                session['user1'] = 'alex'
                session['user2'] = 'alex'
                del session['user2']

                return "内容"

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

        session.py
            #!/usr/bin/env python
            # -*- coding:utf-8 -*-
            import uuid
            import json
            from flask.sessions import SessionInterface
            from flask.sessions import SessionMixin
            from itsdangerous import Signer, BadSignature, want_bytes


            class MySession(dict, SessionMixin):
                def __init__(self, initial=None, sid=None):
                    self.sid = sid
                    self.initial = initial
                    super(MySession, self).__init__(initial or ())


                def __setitem__(self, key, value):
                    super(MySession, self).__setitem__(key, value)

                def __getitem__(self, item):
                    return super(MySession, self).__getitem__(item)

                def __delitem__(self, key):
                    super(MySession, self).__delitem__(key)



            class MySessionInterface(SessionInterface):
                session_class = MySession
                container = {}

                def __init__(self):
                    import redis
                    self.redis = redis.Redis()

                def _generate_sid(self):
                    return str(uuid.uuid4())

                def _get_signer(self, app):
                    if not app.secret_key:
                        return None
                    return Signer(app.secret_key, salt='flask-session',
                                  key_derivation='hmac')

                def open_session(self, app, request):
                    """
                    程序刚启动时执行,需要返回一个session对象
                    """
                    sid = request.cookies.get(app.session_cookie_name)
                    if not sid:
                        sid = self._generate_sid()
                        return self.session_class(sid=sid)

                    signer = self._get_signer(app)
                    try:
                        sid_as_bytes = signer.unsign(sid)
                        sid = sid_as_bytes.decode()
                    except BadSignature:
                        sid = self._generate_sid()
                        return self.session_class(sid=sid)

                    # session保存在redis中
                    # val = self.redis.get(sid)
                    # session保存在内存中
                    val = self.container.get(sid)

                    if val is not None:
                        try:
                            data = json.loads(val)
                            return self.session_class(data, sid=sid)
                        except:
                            return self.session_class(sid=sid)
                    return self.session_class(sid=sid)

                def save_session(self, app, session, response):
                    """
                    程序结束前执行,可以保存session中所有的值
                    如:
                        保存到resit
                        写入到用户cookie
                    """
                    domain = self.get_cookie_domain(app)
                    path = self.get_cookie_path(app)
                    httponly = self.get_cookie_httponly(app)
                    secure = self.get_cookie_secure(app)
                    expires = self.get_expiration_time(app, session)

                    val = json.dumps(dict(session))

                    # session保存在redis中
                    # self.redis.setex(name=session.sid, value=val, time=app.permanent_session_lifetime)
                    # session保存在内存中
                    self.container.setdefault(session.sid, val)

                    session_id = self._get_signer(app).sign(want_bytes(session.sid))

                    response.set_cookie(app.session_cookie_name, session_id,
                                        expires=expires, httponly=httponly,
                                        domain=domain, path=path, secure=secure)

自定义Session

     b、 紧接着管理session(将RequestContext对象(request,session)增加到local中),request(将request新闻打包到Request(environ)对象并复制给requestContext 对                       象),然后拿走cookie中的随机字符串,核实是否有,未有就转换。依照随意字符串,获取服务端session保存的值。把session放到内部存款和储蓄器中,

自定义session

自定义session

     c、  执行wsgi_app方法上边包车型大巴视图函数。实践完视图函数重回到full_dispatch_requesthong ,触发只举行贰遍的装饰器中(触发Flask复信号),

澳门新萄京官方网站 84澳门新萄京官方网站 85

澳门新萄京官方网站 86澳门新萄京官方网站 87

     d、  试行完那一个装饰器,紧接着试行上边包车型客车格外的装饰器,就算那个独特装饰器没有再次回到值,那么rv=None,如果有再次来到值,页面时就显得那些再次回到值,

#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
pip3 install redis
pip3 install flask-session

"""


from flask import Flask, session, redirect
from flask.ext.session import Session


app = Flask(__name__)
app.debug = True
app.secret_key = 'asdfasdfasd'


app.config['SESSION_TYPE'] = 'redis'
from redis import Redis
app.config['SESSION_REDIS'] = Redis(host='192.168.0.94',port='6379')
Session(app)


@app.route('/login')
def login():
    session['username'] = 'alex'
    return redirect('/index')


@app.route('/index')
def index():
    name = session['username']
    return name


if __name__ == '__main__':
    app.run()
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
pip3 install redis
pip3 install flask-session

"""


from flask import Flask, session, redirect
from flask.ext.session import Session


app = Flask(__name__)
app.debug = True
app.secret_key = 'asdfasdfasd'


app.config['SESSION_TYPE'] = 'redis'
from redis import Redis
app.config['SESSION_REDIS'] = Redis(host='192.168.0.94',port='6379')
Session(app)


@app.route('/login')
def login():
    session['username'] = 'alex'
    return redirect('/index')


@app.route('/index')
def index():
    name = session['username']
    return name


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

     e、假使未有重返值,触发推行那多少个视图函数,拿重临值。请求实施完回到后,调用finalize_request,对它的重回值实行李包裹装。

第三方session

第三方session

十六、Flask和Django的区别 

玖.伸手扩张

九.请求扩大

     a、恳请相关的多寡           

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Flask, Request, render_template

app = Flask(__name__, template_folder='templates')
app.debug = True


@app.before_first_request
def before_first_request1():
    print('before_first_request1')


@app.before_first_request
def before_first_request2():
    print('before_first_request2')


@app.before_request
def before_request1():
    Request.nnn = 123
    print('before_request1')


@app.before_request
def before_request2():
    print('before_request2')


@app.after_request
def after_request1(response):
    print('before_request1', response)
    return response


@app.after_request
def after_request2(response):
    print('before_request2', response)
    return response


@app.errorhandler(404)
def page_not_found(error):
    return 'This page does not exist', 404


@app.template_global()
def sb(a1, a2):
    return a1   a2


@app.template_filter()
def db(a1, a2, a3):
    return a1   a2   a3


@app.route('/')
def hello_world():
    return render_template('hello.html')


if __name__ == '__main__':
    app.run()
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Flask, Request, render_template

app = Flask(__name__, template_folder='templates')
app.debug = True


@app.before_first_request
def before_first_request1():
    print('before_first_request1')


@app.before_first_request
def before_first_request2():
    print('before_first_request2')


@app.before_request
def before_request1():
    Request.nnn = 123
    print('before_request1')


@app.before_request
def before_request2():
    print('before_request2')


@app.after_request
def after_request1(response):
    print('before_request1', response)
    return response


@app.after_request
def after_request2(response):
    print('before_request2', response)
    return response


@app.errorhandler(404)
def page_not_found(error):
    return 'This page does not exist', 404


@app.template_global()
def sb(a1, a2):
    return a1   a2


@app.template_filter()
def db(a1, a2, a3):
    return a1   a2   a3


@app.route('/')
def hello_world():
    return render_template('hello.html')


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

                  -Django:参数

 

 

                  -Flask:    基于Local,LocalStark对象

调用方式:{{sb(1,2)}}  {{ 1|db(2,3)}}
调用方式:{{sb(1,2)}}  {{ 1|db(2,3)}}

     b、 多少个请求进入会不会搅乱            

 

 

                  -单线程

10.闪现(flash)

10.闪现(flash)

                  -多线程

session从在在服务端的3个字典中,session保存的多寡取三遍,它仍然会有。而flash是依靠session成立的,flash援助在当中放值,只要在中间取值它就会并未有。闪现便是

session从在在服务端的2个字典中,session保存的数量取贰次,它仍旧会有。而flash是依赖session成立的,flash协助在中间放值,只要在其间取值它就能并未有。闪现正是

                  -协程

在session的底蕴上,把它的值真实的位于session上,当去它的时候不仅仅把它的值取走,还把session的事物去掉。

在session的基本功上,把它的值真实的位于session上,当去它的时候不只有把它的值取走,还把session的东西去掉。

                    解决: from greenlet import getcurrent as get_ident

闪现的用处:

闪现的用途:

十七、**Flask**信号

 

 

    a、 Flask框架中的时限信号基于blinker**

from flask import Flask,session,Session,flash,get_flashed_messages,redirect,render_template,request
app = Flask(__name__)
app.secret_key ='sdfsdfsdf'

@app.route('/users')
def users():
    # msg = request.args.get('msg','')
    # msg = session.get('msg')
    # if msg:
    #     del session['msg']

    v = get_flashed_messages()
    print(v)
    msg = ''
    return render_template('users.html',msg=msg)

@app.route('/useradd')
def user_add():
    # 在数据库中添加一条数据
    # 假设添加成功,在跳转到列表页面时,显示添加成功
    # return redirect('/users?msg=添加成功')
    # session['msg'] = '添加成功'

    flash('添加成功')
    return redirect('/users')


if __name__ == '__main__':
    app.run()
from flask import Flask,session,Session,flash,get_flashed_messages,redirect,render_template,request
app = Flask(__name__)
app.secret_key ='sdfsdfsdf'

@app.route('/users')
def users():
    # msg = request.args.get('msg','')
    # msg = session.get('msg')
    # if msg:
    #     del session['msg']

    v = get_flashed_messages()
    print(v)
    msg = ''
    return render_template('users.html',msg=msg)

@app.route('/useradd')
def user_add():
    # 在数据库中添加一条数据
    # 假设添加成功,在跳转到列表页面时,显示添加成功
    # return redirect('/users?msg=添加成功')
    # session['msg'] = '添加成功'

    flash('添加成功')
    return redirect('/users')


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

    b、安装:澳门新萄京官方网站:Flask首要知识点。 pip3 install blinker**

 

 

    c、11个时限信号

11.蓝图

11.蓝图

1. 内置信号
            10个信号:
                2. request_started = _signals.signal('request-started')                # 请求到来前执行
                5. request_finished = _signals.signal('request-finished')              # 请求结束后执行

                3. before_render_template = _signals.signal('before-render-template')  # 模板渲染前执行
                4. template_rendered = _signals.signal('template-rendered')            # 模板渲染后执行

                2/3/4/5或不执行 got_request_exception = _signals.signal('got-request-exception')    # 请求执行出现异常时执行

                6. request_tearing_down = _signals.signal('request-tearing-down')      # 请求执行完毕后自动执行(无论成功与否)
                7. appcontext_tearing_down = _signals.signal('appcontext-tearing-down')# 请求上下文执行完毕后自动执行(无论成功与否)


                1. appcontext_pushed = _signals.signal('appcontext-pushed')            # 请求app上下文push时执行

                8. appcontext_popped = _signals.signal('appcontext-popped')            # 请求上下文pop时执行

                message_flashed = _signals.signal('message-flashed')                   # 调用flask在其中添加数据时,自动触发

蓝图用于为使用提供目录划分

蓝图用于为使用提供目录划分

     d、flask非能量信号本生自个儿从没,用的是外人的,并且这个时限信号通过装饰器全体得以代表了的,可是Django里面有些非常的
就是这些model操作根本未曾装饰器,正是同过内置的非功率信号来实现的

 

 

十八、django内置的实信号

  • 蓝图URL前缀:xxx = Blueprint('account', __name__,url_prefix='/xxx')
  • 蓝图子域名:xxx = Blueprint('account', __name__,subdomain='admin')
    # 前提需求给配置SELacrosseVELAND_NAME: app.config['SERVER_NAME'] = 'wupeiqi.com:5000'
    # 访问时:admin.wupeiqi.com:5000/login.html
  • 蓝图URL前缀:xxx = Blueprint('account', __name__,url_prefix='/xxx')
  • 蓝图子域名:xxx = Blueprint('account', __name__,subdomain='admin')
    # 前提要求给安插SE科雷傲VE哈弗_NAME: app.config['SERVER_NAME'] = 'wupeiqi.com:5000'
    # 访问时:admin.wupeiqi.com:5000/login.html
Request/response signals
                    request_started             # 请求到来前,自动触发
                    request_finished            # 请求结束后,自动触发
                    got_request_exception       # 请求异常后,自动触发

                Model signals
                    pre_init                    # django的modal执行其构造方法前,自动触发
                    post_init                   # django的modal执行其构造方法后,自动触发

                    pre_save                    # django的modal对象保存前,自动触发
                    post_save                   # django的modal对象保存后,自动触发

                    pre_delete                  # django的modal对象删除前,自动触发
                    post_delete                 # django的modal对象删除后,自动触发

                    m2m_changed                 # django的modal中使用m2m字段操作第三张表(add,remove,clear)前后,自动触发

                    class_prepared              # 程序启动时,检测已注册的app中modal类,对于每一个类,自动触发

                Management signals
                    pre_migrate                 # 执行migrate命令前,自动触发
                    post_migrate                # 执行migrate命令后,自动触发

                Test signals
                    setting_changed             # 使用test测试修改配置文件时,自动触发
                    template_rendered           # 使用test测试渲染模板时,自动触发
                Database Wrappers
                    connection_created          # 创建数据库连接时,自动触发

1二.配备文件

1贰.安插文件

十九、Wtform

 

 

    a、WTForms是三个辅助多个web框架的form组件,首要用于对用户请求数据开展认证。

1. 配置文件
        a. 以后遇到 xxx['xx'] = 123
            - __setitem__
            - 继承dict
            PS: 
                class Foo(dict):
                    def __init__(self,val):
                        dict.__init__(self,val)

                obj = Foo({'xxx':123})
                print(obj)

        b. 配置方式
            # 方式一:
            # app.config['SESSION_COOKIE_NAME'] = 'session_lvning'  #
            # 方式二:
            # app.config.from_pyfile('settings.py')
            # 方式三:
            # import os
            # os.environ['FLAKS-SETTINGS'] = 'settings.py'
            # app.config.from_envvar('FLAKS-SETTINGS')
            # 方式四:
            # app.config.from_object('settings.DevConfig')
1. 配置文件
        a. 以后遇到 xxx['xx'] = 123
            - __setitem__
            - 继承dict
            PS: 
                class Foo(dict):
                    def __init__(self,val):
                        dict.__init__(self,val)

                obj = Foo({'xxx':123})
                print(obj)

        b. 配置方式
            # 方式一:
            # app.config['SESSION_COOKIE_NAME'] = 'session_lvning'  #
            # 方式二:
            # app.config.from_pyfile('settings.py')
            # 方式三:
            # import os
            # os.environ['FLAKS-SETTINGS'] = 'settings.py'
            # app.config.from_envvar('FLAKS-SETTINGS')
            # 方式四:
            # app.config.from_object('settings.DevConfig')

    b、安装: pip3 install wtform

 

 

    c、用途:**

14.中间件

14.中间件

**       1、用户登入注册**

 

 

               当用户登入时候,须要对用户提交的用户名和密码进行各个格式校验。如:

from flask import Flask, flash, redirect, render_template, request

app = Flask(__name__)
app.secret_key = 'some_secret'

@app.route('/')
def index1():
    return render_template('index.html')

@app.route('/set')
def index2():
    v = request.args.get('p')
    flash(v)
    return 'ok'

class MiddleWare:
    def __init__(self,wsgi_app):
        self.wsgi_app = wsgi_app

    def __call__(self, *args, **kwargs):

        return self.wsgi_app(*args, **kwargs)

if __name__ == "__main__":
    app.wsgi_app = MiddleWare(app.wsgi_app)
    app.run(port=9999)
from flask import Flask, flash, redirect, render_template, request

app = Flask(__name__)
app.secret_key = 'some_secret'

@app.route('/')
def index1():
    return render_template('index.html')

@app.route('/set')
def index2():
    v = request.args.get('p')
    flash(v)
    return 'ok'

class MiddleWare:
    def __init__(self,wsgi_app):
        self.wsgi_app = wsgi_app

    def __call__(self, *args, **kwargs):

        return self.wsgi_app(*args, **kwargs)

if __name__ == "__main__":
    app.wsgi_app = MiddleWare(app.wsgi_app)
    app.run(port=9999)

              用户不可能为空;用户长度必须大于陆;

 

 

              密码不可能为空;密码长度必须大于1二;密码必须带有 字母、数字、特殊字符等(自定义正则);

 

 

澳门新萄京官方网站 88澳门新萄京官方网站 89

 

 

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Flask, render_template, request, redirect
from wtforms import Form
from wtforms.fields import core
from wtforms.fields import html5
from wtforms.fields import simple
from wtforms import validators
from wtforms import widgets

app = Flask(__name__, template_folder='templates')
app.debug = True


class LoginForm(Form):
    name = simple.StringField(
        label='用户名',
        validators=[
            validators.DataRequired(message='用户名不能为空.'),
            validators.Length(min=6, max=18, message='用户名长度必须大于%(min)d且小于%(max)d')
        ],
        widget=widgets.TextInput(),
        render_kw={'class': 'form-control'}

    )
    pwd = simple.PasswordField(
        label='密码',
        validators=[
            validators.DataRequired(message='密码不能为空.'),
            validators.Length(min=8, message='用户名长度必须大于%(min)d'),
            validators.Regexp(regex="^(?=.*[a-z])(?=.*[A-Z])(?=.*d)(?=.*[$@$!%*?&])[A-Za-zd$@$!%*?&]{8,}",
                              message='密码至少8个字符,至少1个大写字母,1个小写字母,1个数字和1个特殊字符')

        ],
        widget=widgets.PasswordInput(),
        render_kw={'class': 'form-control'}
    )



@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        form = LoginForm()
        return render_template('login.html', form=form)
    else:
        form = LoginForm(formdata=request.form)
        if form.validate():
            print('用户提交数据通过格式验证,提交的值为:', form.data)
        else:
            print(form.errors)
        return render_template('login.html', form=form)

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

 

 

app.py

 

 

澳门新萄京官方网站 90澳门新萄京官方网站 91

 

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>登录</h1>
<form method="post">
    <!--<input type="text" name="name">-->
    <p>{{form.name.label}} {{form.name}} {{form.name.errors[0] }}</p>

    <!--<input type="password" name="pwd">-->
    <p>{{form.pwd.label}} {{form.pwd}} {{form.pwd.errors[0] }}</p>
    <input type="submit" value="提交">
</form>
</body>
</html>

 

 

login

 

 

二十、SQLALchemy

 

 

    a、介绍 :      

      

      

           SQLALchemy是3个基于Python完成的O安德拉M框架。该框架是塑造在DB API之上,使用关系对象映射举行数据库操作

 

 

           简言之便就是:将类和目的转变到SQL,然后使用数据API实行SQL并获取试行的结果

澳门新萄京官方网站:Flask首要知识点。       

       

    b、安装: pip3 install SQLALchemy

 

 

    c、组成都部队分**

 engine,                                     框架的引擎

     Connection  Pooling  ,                      数据库连接池

     Dialect,                                    选择链接数据库的DB  API种类

     Schema /Types,                              架构和类型     

     SQL Exprression Language,                   SQL表达式语言

    d、SQLALcheam外省不能操作数据库,其必须来pymysql等第一方插件, Dialect用于数据API的调换,依照铺排文件的不等**

调用不相同的数据库API,从而完结对数据库的操作

MySQL-Python
    mysql mysqldb://<user>:<password>@<host>[:<port>]/<dbname>

pymysql
    mysql pymysql://<username>:<password>@<host>/<dbname>[?<options>]

MySQL-Connector
    mysql mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname>

cx_Oracle
    oracle cx_oracle://user:pass@host:port/dbname[?key=value&key=value...]

更多:http://docs.sqlalchemy.org/en/latest/dialects/index.html

 

 

  

 

本文由澳门新萄京官方网站发布于www.8455.com,转载请注明出处:澳门新萄京官方网站:Flask首要知识点

关键词: