flask 之进阶

一.flask 之路由

       url_for 方向解析路由

     1.一个装饰器

    @app.route('/')       1.end point 没有指定时默认为 函数的名 endpoint='index'     就反向解析到路由  'index'----> '/' 
     def index():            2.指定 endpoint = 'wyc'       'wyc' ------> '/'
         return '123'

      2.两个装饰器

def wrpaer(fn):
    def inner(*args,**kwargs):
        ret=fn(*args,**kwargs)
        return ret
    return inner

@app.route('/')                @app.route('/detail')
@wrpaer                        @wrpaer   
def index():                   def detail():
    return '123'                  return '123'

        装饰器:  wrpaer(index) --->inner   所以现在两个 视图函数的名字就是inner   而默认endpoint 使用函数名反向解析 'inner'

        'inner' ---->'/'     'inner' ---> 'detail'            就会报错  所以使用endpoint=''  指定一个不同的字符串 就可以解决问题

     3.视图函数的几个参数

      method=[]   endpoint=''     strict_slashes是否严格遵循路由地址  默认为True    redirect_to=''   重定向 视图函数就不执行了

      defaults={'a':1}   给函数传一个默认值       视图函数必须接受这个值

     4.动态路由

         app.route('/<id>/<int:num>/<string: str>')     默认string   视图函数必须接受这个参数 id num ,string

     5.flask 实例化配置 参数

       template_folder='templates',    模板存放地址,网页

       static_folder='statics',              静态文件目录地址          默认是  static

       static_url_path='/statics'          静态文件访问地址            前面必须加一个   /

        static_host='www.baidu.com'       把 自己的域名更换

      6.flask 对象配置

        1. 直接app.来配置         app.secret_key=' '  使用session   配置     

             app.session_cookie_name=''    cookie 的名字        app.debug=True

         2. 使用文件配置  新建一个setting  文件                app.config.from_object(setting.Test)   --> 可以随意切换

class Test():
    SECRET_KEY='TEST'
    SESSION_COOKIE_NAME='test'
    DEBUG=True
class Debug():
    SECRET_KEY='TEST'
    SESSION_COOKIE_NAME='test'

  7.蓝图 

       1.新建一个app01的包  新建user.py 文件   

from flask import Blueprint,render_template
user_blue=Blueprint('user',__name__,url_prefix='/user',template_folder='user_temp')
@user_blue.route('user_add')
def user_add():
    return render_template('user_add.html')

            ur_prefix 的意思 就是 蓝图下面的 视图 url 前都加上一个/user 才能访问  ,其他用法 与flask 一样

      2.  1.导入:from app01 import user        2.注册 :   app.register_blueprint(user.user_blue) 

   8.flash  闪存

              from flask import flash,get_flash_messages
              flash("ddd","tag")
              get_flash_messages(["tag"])

二.特殊装饰器  相当于中间件

@app.before_request             进入视图函数之前
def is_login():
    if request.path == '/login':
        if session.get('user'):
            return None       跳过
        else:
            return '缺失session'
    return None

      这样就可以 让没有session 的用户 无法登录      return None 的意思就是继续执行 放行   如果return 了

      resposne  后面的视图就不执行了

@app.after_request          视图结束之后,返回浏览器之前,如果有多个   每一个按倒序执行
def affter(res):             如果before_request 有一个出现异常      每一个按倒序执行
    return res 

       任何返回给 浏览器响应之前都 执行 affter 函数  和django不一样的是request和resposne 不一一对应

       before_request返回resposne 时    执行每一个  affter_request               和写的循序倒序执行 

     3.@app.errorhandler(404)   处理指定的异常

@app.errorhandler(404)
def error(arg):       arg是原始错误信息
    return '页面不存在'

      4.@app.template_global()      全局函数   每个模板都能使用          5. @app.template_filter()           偏函数

     三.flask 之 CBV

    from flask import views
    class LoginView(views.MethodView):
        def get(self):          #method=['GET','POST'] 写了什么才执行
            return
        def post(self):
            return
    app.add_url_rule("/login",endpoint=None,view_func=LoginView.as_view(name="login"))

  as_view() 必须传一个参数    可以随意取

     四. flask 之 第三方

     1.session     

              from flask_session import Session                      pip install  flask_session

              from flask  import  session                                  原始session 还是得导入 

              app.config['SESSION_TYPE']= ' redis  '              配置使用 redis 来存储 加密session 

              app.config[' SESSION_REDIS'] = Redis('127.0.0.1'  ,6379, db= 1 )               配置连接redis 的第几个数据库  一共0-15

              SESSION(app)         重新设置app   

        @app.route('/login')
        def login():
            session['user']='WYC'      这里的session 就不需要普通的session_key了   这里的是存储在redis
            return 'login'              经过加密的session

     2.wtforms

       1. form 表单写法

from flask import Flask,request,render_template,views
from wtforms.fields import simple,core
from wtforms import Form
from wtforms import validators
class LoginForm(Form):
    username=simple.StringField(             普通的都是simple 里面的
        label='用户名',
        validators=[
            validators.DataRequired(message='不能为空'),
            validators.Email(message='格式不正确'),
        ]
    )
    password=simple.PasswordField(
        label='密码',
        validators=[
           validators.Length(min=3,max=10,message='大于三位,小于6位'),
           validators.Regexp(regex='^[a-zA-Z]+',message='密码以字母开头'),
        ]
    )
    repassword = simple.PasswordField(
        label='重复密码',
        validators=[             指向前一个字段的 字符串
            validators.EqualTo(fieldname='password',message='两次输入不一致!!'),
        ]
    )
    gender=core.RadioField(
        label='性别:',
        coerce=int,
        choices=((1,'男'),(2,'女')),
        default=1
    )
    hobby=core.SelectMultipleField(         选择框时  使用core
        label='喜好:',
        coerce=int,
        choices=(
            (1,'a'),
            (2,'b'),
            (3,'c'),
            (4,'d'),
        ),
        default=(2,4)
    )
   submit= simple.SubmitField(
        label='提交'
    )

          2. CBV 校验 :

class LoginClass(views.MethodView):
    def get(self):
        login=LoginForm()                 实例化LoginForm 表单  再传入Html中
        return render_template('login.html',login=login)
    def post(self):
        login=LoginForm(request.form)     用户数据 传入LoginForm做校验 再判断是否校验成功
        if login.validate():         True 或False 
            return 'login success!'
        return render_template('login.html',login=login)     False 就把错误信息传回Html
app.add_url_rule('/login',view_func=LoginClass.as_view('login'))


class RegClass(views.MethodView):
    def get(self):
        reg=RegForm()
        return render_template('reg.html',reg=reg)
    def post(self):
        reg=RegForm(request.form)
        if reg.validate():
            return 'reg success!'         reg.get('username')  取值方法
        return render_template('reg.html',reg=reg)
app.add_url_rule('/reg',view_func=RegClass.as_view('reg')) 
  指定RegClass  的路由为/reg   函数为 RegClsass.as_view('reg')   reg是随便的

       3.页面渲染

<form action="" method="post" novalidate>         novalidate 取消浏览器校验是否为空
    {% for r in reg %}
    <p>{{ r.label }}{{ r }}{{ r.errors.0 }}</p>      r.errors 为一个列表
    {% endfor %}
</form>

五.数据库池

import pymysql
from DBUtils.PooledDB import PooledDB
POOL = PooledDB(
    creator=pymysql,   使用链接数据库的模块
    maxconnections=6,   连接池允许的最大连接数,0和None表示不限制连接数
    mincached=2,   初始化时,链接池中至少创建的空闲的链接,0表示不创建
    maxcached=5,   链接池中最多闲置的链接,0和None不限制
    maxshared=3,   python中设置没用
    blocking=True,  连接池中如果没有可用连接后,是否阻塞等待。True,等待;False不等待然后报错
    maxusage=None,  一个链接最多被重复使用的次数,None表示无限制
    setsession=[], 开始会话前执行的命令列表。如:["set time zone ..."]
    ping=0,       通常为0
    host='127.0.0.1',
    port=3306,
    user='root',
    password='',
    database='db7',
    charset='utf8'
)
def func():
    conn = POOL.connection()
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    cursor.execute('select * from userinfo')
    result = cursor.fetchall()
    print(result)
    conn.close()  
func()

六.flask  请求上下文 

   为解决 多个用户访问 开启多个线程 导致的 request对象 混乱的 现象,  利用 栈,偏函数 ,python 字典 这几个概念  

    将每个 线程的 key设置为 线程的pid    值为序列化 好 的 request session 对象 取得时候就使用 线程的id 取保证数据的安全性

    和高效性,但每一个线程都要复制一个新的地址牺牲了 内存空间

      原理参数梳理:   1. environ是请求的信息,2.LocalProxy 偏函数   3. 

class wyc():
    def __call__(self):
        print()
w=wyc()
w()  w对象再加括号 相当于执行call方法              

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值