Flask框架学习笔记_1

虚拟环境说明

  • 想在另一台电脑同步该虚拟环境中所安装的包

    • 首先把该电脑的虚拟环境中的包指定到一个文件中

      pip freeze > requirements.txt
      
    • 把该文件给需要同步的电脑,在那太电脑中先创建好一个虚拟环境

    • 同步

      pip install -r requirements.txt
      

Flask框架

简介 官方文档

  • 它是一个轻量级的框架,只提供web框架的核心功能,比较的自由、灵活、高度定制
  • 它本身相当于一个内核,其他几乎所有功能都要用到扩展,都需要第三方的扩展来实现
  • Flask框架的核心:WerkzeugJinja2

Flask扩展包

  • Flask-SQLalchemy:操作数据库
  • Flask-migrate:管理迁移数据库
  • Flask-Mail:邮件
  • Flask-WTF:表单
  • Flask-script:插入脚本
  • Flask-Login:认证用户状态
  • Flask-RESTful:开发REST API的工具
  • Flask-Bootstrap:集成前端Twitter Bootstrap框架
  • Flask-Moment:本地化日期和时间

安装

pip install flask==0.10.1

一个简单的Flask程序

# 导入Flask类
from flask import Flask

#创建flask的应用对象
app = Flask(__name__)

# 装饰器的作用是将路由映射到视图函数index
@app.route('/')
def index():
    '''定义视图函数'''
    return 'Hello World'

# Flask应用程序实例的run方法启动WEB服务器
if __name__ == '__main__':
    app.run()
  • __name__:表示当前的模块的名字
  • @app.route('/'):用装是器来实现路由的映射
  • app.run()的参数,可以传递hostportdebug

创建APP对象

  • 初始化参数:
    • static_url_path:
    • static_folder: 默认‘static’
    • template_folder: 默认‘templates’

Flask配置参数设置

  • 法1:创建一个文件 config.cfg (文件名随意指定),在里面设置配置,然后使用配置文件

    app.config.from_pyfile(“yourconfig.cfg”)
    
  • 法2:使用对象配置参数,在程序里用一个类来定义配置参数

    class Config(object):
        DEBUG = True
    
    app.config.from_object(Config)
    
  • 法3:直接操作config的字典对象

    app.config["DEBUG"] = True
    

在视图中读取配置参数

  • 法1:app.config['xxx']app.config.get('xxx') (前提是配置信息在同一程序中,还有尽量用get,不然若取不到的话会报错)

  • 法2:若在模块中无法直接拿到app,可以用current_app,其用法与app 的用法一样

    from flask import aurrent_app
    aurrent_app.config.get("DEBUG")
    

视图函数的路由规则

  • @app.route('/post', methods=['POST'])

    methods可以指定该url可以由什么方式请求,列表,可以写多个

  • 查看flask中路由的信息:app.url_map,显示形式为下

    Map([<Rule '/' (HEAD, OPTIONS, GET) -> index>,
     <Rule '/python/<filename>' (HEAD, OPTIONS, GET) -> static>])
    
    
  • 几种情况

    • ①同样的url,访问不同的视图函数

      url和请求方式一样,谁在前面就访问哪个视图函数

    • 不同的url,访问相同的视图函数

      装饰器是可以叠加的,在同一视图函数上用不同的@app.route配置

  • Flask中的反向解析

    from flask import redirect
    @app.route('/login')
    def login():
    	url = url_for('index')
        return redirect(url)   # 重定向
    
    

    url_for('index') 可以进行反向解析,index 是通过视图函数的名字找到视图对应的url路径

  • 动态路由

    @app.route('/goods/<int:goods_id>')
    def goods_detail(goods_id)
    	pass
    
    

    int 是一个转换器,意思就是如127.0.0.1:5000/goods/12匹配到int类型就符合规则,就把匹配到的值赋值自己定义的goods_id这个变量,然后在定义视图函数时需传参goods_id来接受数据

    • 几种转换器
      • int:接受整数
      • float:同int,但接受的是浮点数
      • path:和默认的相似,但也接受斜线(默认就是普通的字符串规则,除了斜线)
  • 自定义转换器

    • 1.用类的方法定义

      from werkzeug.routing import BaseConverter
      class RegexConverter(BaseConverter):
          """"""
          def __init__(self, url_map, regex):
              # 调用父类的初始化方法
              super(RegexConverter, self).__init__(url_map)
              # 将正则表达式的参数保存到对象的属性中,flask会去使用这个属性来进行路由的正则匹配
              self.regex = regex
      
      
    • 2.将自定义的转换器添加到flask的应用中

      app.url_map.converters["re"] = RegexConverter  # re为你给转换器定义的名字
      
      
    • 3.使用

      @app.route("/send/<re(r'1[34578]\d{9}'):mobile_num>")  # 因为自定义的是re的万用转换器,直接在里面写正则就好
      
      

      这种情况下,使用url_for()不仅需要传递视图函数的名字,还需mobile_num

      url = url_for("send_sms", mobile_num="18922222222")

获取请求参数

  • request 中包含了前端发送过来的所有请求数据,是 Flask 中表示当前请求的 request 对象,request对象中保存了一次HTTP请求的一切信息

  • request.form可以直接提取请求体中的表单格式的数据,是一个类字典的对象

    通过get方法只能拿到多个同名参数的第一个,getlist获取全部

    name = request.form.get("name")
    name_li = request.form.getlist("name")
    
    
  • 如果是请求体的数据不是表单格式的(如json格式),可以通过request.data获取

  • args是用来提取url中的参数(查询字符串)

  • request 常用的属性

    属性说明类型
    data记录请求的数据,并转为字符串
    form记录请求中的表单数据MultiDict
    args记录请求中的查询参数MultiDict
    cookies记录请求中的cookie信息Dict
    headers记录请求中的报文头EnvironHeaders
    method记录请求中的HTTP请求方法GET/POST
    url记录请求的URL地址string
    files记录请求上传的文件
  • 在视图函数中,可能对不同的请求方式会有不同的处理,这时就可以用

    if request.method == 'GET':
    	pass
    elif request.method == 'POST':
        pass
    
    
  • 上传文件

    • 已上传的文件存储在内存或是文件系统中一个临时的位置,你可以通过请求对象的 files 属性访问它们。每个上传的文件都会存储在这个字典里。

    • request.files.get()可以接受前端上传的文件

      @app.route("/upload", methods=["POST"])
      def upload():
          """接受前端传送过来的文件"""
          file_obj = request.files.get("pic")
          if file_obj is None:
              # 表示没有发送文件
              return "未上传文件"
      
          # 直接使用上传的文件对象保存
          file_obj.save("./demo1.png")
          return "上传成功"
      
      

    自定义异常处理

    • abort()函数

      • 使用abort函数可以立即终止视图函数的执行,并可以返回给前端特定的信息

        from flask import Flask, request, abort, Response
        app = Flask(__name__)
        
        @app.route("/login", methods=["GET"])
        def login():
            # name = request.form.get()
            # pwd = request.form.get()
            name = ""
            pwd = ""
            if name != "zhangsan" or pwd != "admin":
                # 1 传递状态码信息, 必须是标准的http状态码
                abort(404)
                # # 2. 传递响应体信息
                # resp = Response("login failed")
                # abort(resp)
            return "login success"
        
        
    • 自定义异常处理

      # 定义错误处理的方法
      @app.errorhandler(404)
      def handle_404_error(err):
          """自定义的处理错误方法"""
          # 这个函数的返回值会是前端用户看到的最终结果
          return u"出现了404错误, 错误信息:%s" % err
      
      if __name__ == '__main__':
          app.run(debug=True)
      
      

      即这个函数回去处理404页面错误,这个函数的返回值会返回给前端

设置响应信息

  • 使用元组返回自定义的响应信息,也可以使用字典

    @app.route("/index")
    def index():
        return "index page", 400, [("Name", "Fxh"), ("Age", "21")]
    
    

    index page:响应体

    400:状态码

    [("Name", "Fxh"), ("Age", "21")]:响应头

  • 使用make_response 来构造响应信息

    @app.route("/index")
    def index():
    	resp = make_response("index page 2")
        resp.status = "999 说明信息"  # 设置状态码,后面为你对该状态码的说明信息
        resp.headers["Name"] = "Fxh"  # 设置响应头
        return resp
    
    

返回json数据的方法

  • json就是字符串

  • 法1:直接操控json模块

    import json
    @app.route("/index")
    def index():
        data = {'name':'fxh','age':21}
        json_str = json.dumps(data)
        return json_str, 200, {"Content-Type": "application/json"}
    
    
    • json.dumps(字典)------->Python字典转换为json字符串
    • json.loads(字符串)------>字符串转为Python字典
  • 法2:使用 jsonify 返回 json 数据

    • jsonify帮助转为json数据,并设置响应头 Content-Type 为application/json

    • 可以把data当成参数传递给jsonify ,也可以传参时直接写

      return jsonify(data)
      #####
      return jsonify(name="sz", age=21)
      
      

cookie的使用

  • 设置cookie

    from flask import Flask, make_response, request
    
    app = Flask(__name__)
    
    @app.route("/set_cookie")
    def set_cookie():
        resp = make_response("success")
        # 设置cookie, 默认有效期是临时cookie,浏览器关闭就失效
        resp.set_cookie("name", "fxh")
        # max_age设置有效期,单位:秒
        resp.set_cookie("name", "fxh", max_age=3600)
        # cookie的添加实则就是在响应头里添加字段,所以也可以直接写进响应头里
        resp.headers["Set-Cookie"] = "name=fxh; Expires=Sat, 18-Nov-2019 04:36:04 GMT; Max-Age=3600; Path=/"
        return resp
    
    
  • 获取cookie

    @app.route("/get_cookie")
    def get_cookie():
        c = request.cookies.get("name")
        return c
    
    
  • 删除cookie

    @app.route("/delete_cookie")
    def delete_cookie():
        resp = make_response("del success")
        # 删除cookie
        resp.delete_cookie("name")
        return resp
    
    

session

  • 机制[外链图片转存失败(img-GXxqbQFo-1568046046739)((https://FXHao.github.io/images/posts/Flask/session机制.png)]

  • session设置

    from flask import Flask, session, current_app
    app = Flask(__name__)
    
    # flask的session需要用到的秘钥字符串
    app.config["SECRET_KEY"] = "dhsodfhisfhosdhf29fy989"
    
    @app.route("/login")
    def login():
        # 设置session数据
        session["name"] = "fxh"
        session["mobile"] = "18611111111"
        return "login success"
    
    @app.route("/index")
    def index():
        # 获取session数据
        name = session.get("name")
        return "hello %s" % name
    
    
  • session默认是储存在cookie里面的,也可以存在数据库redis文件程序内存里,但如果存在程序内存中(在程序中定义一个全局变量存储),最后部署服务器时,在多个服务器之间,用户有可能在1号服务器登录,然后过了会又在2号服务器登录,而两个服务器的全局变量不是同步的,这时2号服务器就没有该用户刚登录时设置的session数据,当然这种情况也可以适当的解决,比如在nginx调度时可以给它一个规则,某个地区的用户分配到哪个服务器

上下文

  • 相当于一个容器,保存了Flask程序运行过程中的一些信息

  • 请求上下文requestsession都属于请求上下文对象

    • request:封装了HTTP请求的内容,针对的是http请求。如:user = request.args.get('user'),获取的是get请求的参数

    • session:用来记录请求会话中的信息,针对的是用户信息。如:session['name'] = user.id,可以记录用户信息,还可以通过session.get('name')获取用户信息

    • Django中,request是局部变量,所以每个对象请求时都是不同的,而在Flask中,request则是全局变量,它是如何区分request对象是哪个用户的呢?

      • 其实在Flask中,全局变量使用起来相当于线程局部变量,它会把建立一个request字典,然后用户A请求时,就建立一个线程A放进request中,然后线程A中保存着用户A请求发送的数据,这时如果又有一个用户B来请求时,就又会建立一个线程B来服务用户B

        request = {
            '线程A':{
                from:{'name':'xxx'}
                args:xxx
            }
            '线程B':{
                xxxx
            }
        }
        
        
  • 应用上下文current_app和g都属于应用上下文对象

    • current_app:表示当前运行程序文件的程序实例
    • g:处理请求时,用于临时存储的对象,每次请求都会重设这个变量

请求钩子

  • 请求钩子是通过装饰器的形式实现,Flask支持如下四种请求钩子

    装饰器功能
    @app.before_first_request在处理第一个请求前运行
    @app.before_request在每次请求前运行
    @app.after_request如果没有未处理的异常抛出,在每次请求后运行
    @app.teardown_request在每次请求后运行,即使有未处理的异常抛出
  • 请求钩子在每个视图函数被请求时都会执行(类似于Django中的中间件),也可以让钩子所装饰的函数根据不同的视图函数而执行不同的程序

    @app.teardown_request
    def handle_teardown_request(response):
        """在每次请求 (视图函数处理)之后都被执行, 无论视图函数是否出现异常,都被执行, 工作在非调试模式时 debug=False"""
        path = request.path
        if path == url_for("index"):
            print("在请求钩子中判断请求的视图逻辑: index")
        elif path == url_for("hello"):
            print("在请求钩子中判断请求的视图逻辑: hello")
        print("handle_teardown_request 被执行")
        return response
    
    

Flask-Script 扩展命令行

  • 通过使用Flask-Script扩展,我们可以在Flask服务器启动的时候,通过命令行的方式传入参数。而不仅仅通过app.run()方法中传参

  • 安装:pip install Flask-Script

  • 使用:

    from flask import Flask
    from flask_script import Manager
    
    app = Flask(__name__)
    #创建Manger管理类对象
    manager = Manager(app)
    
    @app.route('/')
    def index():
        pass
    
    if __name__ == "__main__":
        manager.run()
    ###############
    # 这时启动就可以在终端中用下面命令启动
    python 该程序所在的文件名 runserver  # 后面可以加--help来查看参数
    
    

  • 先写这么多吧,剩下的学完在继续写
  • 加油吧,每天积累一点!!!!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值