Flask

面向简单需求和小型应用的框架

特点

  1. 内置开发服务器和调试器
  2. 与python的单元测试无缝连接
  3. 使用Jinja2模板(HTML模板)
  4. 完全兼容WSGI
  5. 基于Unicode编码

安装

  1. pip install flask
  2. pip install sqlalchemy flask-wtf

HelloWorld

from flask import Flask
from flask import render_template
from flask import Mark

app = Flask(__name__)

@app.route('/')	#绑定路由
def hello_world():
    return 'Hello World!'

@app.route('/hello/')
@app.route('/hello/<name>')
def hello(name=None):
    name = Markup(name)	#对字符串做转义处理,比如‘>’转成&gt
    return render_template('hello.html',name=name)	#hello.html文件保存到templage目录下

# return redirect('/check')	重定向
# return abort(400)	返回400错误

@app.errorhandler(400)
def bad_request(error):
    return render_template('bad_request.html',400)

if __name__ == '__main__':
    app.run(host='0.0.0.0',port=80,debug=false)	#运行应用,关闭调试模式
<!doctype html>
<title>Hello from Flask</title>
{% if name %}
	<h1>
    	Hello {{ name }}    
	</h1>
{% else %}
	<h1>
    	Hello World!    
	</h1>
{% endif %}

路由

  1. 路径中添加变量:

    1. @app.route('/login/')
    2. @app.route('/login/<int:number>') 此时number传到方法的就是整型而不是字符串
  2. 结尾都要加‘/’

  3. Http方法绑定

    1. @app.route('/sendMessage',method=['GET','POST'])
  4. 路由地址方向生成

    import flask import Flask,url_for
    
    app = Flask(__name__)
    @app.route('/')
    def f_root():pass
    @app.route('/industry')
    def f_industry():pass
    @app.route('/book/<book_name>')
    def f_book():pass
    
    with app.test_request_context():
    	print(url_for('f_root'))	#输出:/
    	print(url_for('f_industry',name='web'))	#输出:/industry?name=web
    	print(url_for('f_book',book_name='Python Book'))	#输出:/book/Python%20Book
    

Context

  1. 会话上下文

    1. 会话与用户是一对一的关系
    2. 通过Cookie实现
      1. SessionID
    3. from flask import session
      1. session['xxx']=yyy
      2. session.get('xxx')
      3. session.new 判断session是不是新建的
      4. session.moidified 判断session是否被修改
  2. 应用全局对象

  3. from flask import g

  4. 一般用来定义数据库连接和断开

  5. 请求上下文

    1. from flask import request

    2. 属性名称 访问URL返回的结果
      base_url http://localhost/app/page.html
      path /page.html
      script_root /app
      url http://localhost/app/page.html?x=y
      url_root http://localhost/app/page.html
    3. 属性 作用
      form POST或PUT的表单数据
      args URL中的参数
      values 上面两个属性的所有值
      cookies Cookie数据
      headers HEAD数据
      data MIMETYPE类型数据
      files FileStorage类型数据
      method 访问方式(POST,PUT,GET等)
      json 解析json数据
      on_json_loading_failed(e) json数据解析失败的回调
  6. 回调接入点

    1. @app.before_request:请求调用前处理
    2. @app.after_request:请求调用后处理
    3. @app.teardown_request:请求调用后强制处理

JinJa2

  1. {{}}:变量或表达式,{%%}:逻辑控制,{##}:注释

  2. 过滤器

    过滤器 描述
    abs(number) 绝对值
    attr(object,name) 获取指定属性
    capitalize(s) 首字母大写
    center(value,width) 字符串居中
    default(value,default_value,boolean) 若无值则返回默认值
    dictsort(value,case_sensitive,by) 以by的值来排序
    escape(s) 转换为HTML表达方式
    filesize(value,binary) 文件大小单位
    first(sequence) 第一个元素
    float(value,default) float类型
    forceescape(value) 强制HTML转码
    format(value,*attribute) 字符串格式化
    groupby(value,attribute) 按照共有属性分组
    indent(string,width,indentfirst) 缩进
    int(value,,default) int类型
    join(value,d=',') 字符串使用逗号连接
    last(seq) 最后一个元素
    length(obj) 对象长度
    list(value) 转成列表
    lower(string) 转小写
    pprint(value,verbose) 格式化打印
    random(seq) 随机元素
    replace(string,old,new,count) 替换
    reverse(value) 倒序
    safe(value) 标记传入的值是安全的
    slice(value,slices,fill_width) 切片
    sort(value,reverse,case_sensitive,attribute) 排序
    string(object) 转字符串
    striptags(value) 去除标签
    sum(iterable,attribute,start) 求和
    title(s) 以标题形式展示
    trim(value) 去除首位空格
    truncate(s,length,killwords,end) 省略字符串
    upper(s) 转大写
    wordcount(s) 单词个数
    wordwrap(s,width,break_long_words,wrapstring) 字符串分析处理
  3. 流程控制

    1. 测试

      1. is

      2. 判断 描述
        allable(obj) 是否可调用
        defined(value) 是否定义
        divisibleby(value,num) 是否可被num整除
        escaped(value) 是否被转码
        even(value) 是否偶数
        iterable(value) 是否可迭代
        lower(value) 是否小写
        none(value) 是否为空
        number(value) 是否数字
        odd(value) 是否奇数
        sameas(value,order) 是否在内存的同一块地址
        sequence(value) 是否序列
        undefined(value) 是否未定义
        upper(value) 是否大写
        string(value) 是否字符串
    2. 判断:{% if %}...{% elif %}...{else}...

    3. 循环:{% for %}...

      1. 特殊变量

        变量 描述
        loop.index 迭代的次数(从1开始)
        loop.index0 迭代的次数(从0开始)
        loop.revindex 到迭代结束的次数(从1开始)
        loop.revindex0 到迭代结束的次数(从0开始)
        loop.first 是否第一次迭代
        loop.last 是否最后一次迭代
        loop.length 迭代长度
        loop.cycle 在一串序列间取值的辅助函数
  4. 继承

    1. {% block xxx %}...

SQLAlchemy

  1. 定义表

    1. from sqlalchemy.ext.declarative import declarative_base
      1. Base = declarative_base()
    2. 表类继承Base类
      1. __tablename__=u'account' 表在数据库中实际的名称
    3. from sqlalchemy import Column,Integer,String
      1. id = Column(Integer,primary_key=True)
      2. user = Column(String(50),nullable=False)
  2. 定义数据库链接

    1. from sqlalchemy import create_engine

    2. from sqlalchemy.orm import scoped_session,sessionmaker

    3. 创建链接

      1. engine = create_engine(db_connect_string,connect_args)
      2. db_connect_string格式:[database_type]😕/[user_name]:[password]@[domain]:[port]/[database]?[parameters]
        1. 例如:mysql:v_user:v_pass@localhost:3306/test_database?charset=utf8
    4. 建立会话类型

      1. SessionType = scoped_session(sessionmaker(bind=engine,expire_on_commit=False))

      2. 需要定义获取会话类型方法

        deg GetSession():
        	return SessionType()
        
      3. session.commit()、session.rollback()、session.close()、session.commit()

      4. 定义自动进行事务处理的函数

        from contextlib import contextmanager
        @contextmanager
        def session_scope():
        	session = GetSession()
        	try:
        		yield session
        		session.commit()
        	expect:
        		session.rollback()	#异常时自动回滚
        	finally:
        		session.close()	#退出时自动关闭,关闭时会自动提交
        
  3. 操作

    1. with session_scope as session:
    2. 查询:session.query().filter() 有or_、and_,两个都需要import,在filter中使用
      1. first()
      2. all()
      3. filter可以使用like
      4. in_
      5. is_,isnot
      6. 连接查询join()
    3. 新增:session.add()
    4. 删除:session.delete()
    5. 关系
      1. ForeignKey():外键设置
      2. relationship("子表类名",backref="表名",cascade='all')
        1. save_update
        2. delete
        3. refresh-expire
        4. all
      3. 一对多:一张父表、一张子表
      4. 多对多:一张关系表(即父表)、多张子表
  4. 表单

    1. Form类
      1. from flask.ext.wtf import Form
    2. Field
      1. from wtforms import StringField,BooleanField,HIddenField,TextField,DateTimeField
    3. Validator
    4. 显示表单
      1. return render_template('xxx.html',form=form)
    5. 获取表单数据
      1. form.validate():判断数据是否合法
      2. form.xxx.data

REST

REST:表述性状态传递

  1. 调用形式
    1. GET/resource:查询集合
    2. GET/resource/ID:查询个体
    3. POST/resource:新增个体或集合
    4. PUT/resource/ID:全量修改个体
    5. PATCH/resource/ID:部分修改个体
    6. DELETE/resource/ID:删除个体

Restless插件

  1. 实例化管理者对象

    import flask_restless
    # 实例管理这对象,关联应用和数据库对象
    manager = flask_restless.APIManager(app,flask_sqlalchemy_db=db)
    
  2. 建立Restful接口

    manager.create_api(XXX,methods=['GET','POST','DELETE'])
    
  3. 定制接口(以下都是create_api的参数)

    1. url_prefix:定义接口的UIRL前缀

    2. allow_patch_many:是否允许patch

    3. allow_delete_many:是否允许delete

    4. include_colums:定义需要在接口可见的属性

    5. exclude_columns:和include_columns相反

    6. preprocessors:接口调用前调用函数

      manager.create_api(XXX,preprocessors={'POST'=[foo],'GET_SINGLE'=[trace_log]})
      # []中的是方法名
      
    7. postprocessors:接口调用后调用函数

      含义
      POST post请求时被调用
      GET_SINGLE get单个时被调用
      GET_MANY get集合时被调用
      PATCH_SINGLE patch单个时被调用
      PATCH_MANY patch集合时被调用
      PUT_SINGLE put单个时被调用
      PUT_MANY put集合时被调用
      DELETE_SINGLE delete单个时被调用
      DELETE_MANY delete集合时被调用

跨域请求

  1. 跨域请求原理:
    在 HTML 中,<a>, <form>, <img>, <script>, <iframe>, <link> 等标签以及 Ajax 都可以指向一个资源地址,而所谓的跨域请求就是指:当前发起请求的域与该请求指向的资源所在的域不一样。这里的域指的是这样的一个概念:我们认为若协议 + 域名 + 端口号均相同,那么就是同域。

    举个例子:假如一个域名为a.com的网站,它发起一个资源路径为a.com/addUser的 Ajax 请求,那么这个请求是同域的,因为资源路径的协议、域名以及端口号与当前域一致(例子中协议名默认为http,端口号默认为80)。但是,如果发起一个资源路径为b.cn/addUser的 Ajax 请求,那么这个请求就是跨域请求,因为域不一致,与此同时由于安全问题,这种请求会受到同源策略限制

  2. pip install flask_cors

  3. # run.py
    from flask_cors import CORS
    app = Flask(__name__)
    CORS(app,supprts_credentials=True)
    
    if __name__=="__main__":
    	app.run(host='',port=)
        
    # restFulRun.py
    import environment
    environment.init("restful")    
    from app import app
    from flask_restful import Api
    from flask_cors import CORS
    from app.Controllers.RestfulController import TodoList
    
    api = Api(app)
    api.add_resource(TodoList, '/todos')
    app = app
    CORS(app, supports_credentials=True)
    if __name__ == '__main__':
        app.debug = False
        app.run(host='0.0.0.0', port=502)
    
posted @ 2021-12-08 11:41  注入灵魂  阅读(74)  评论(0)    收藏  举报