zoukankan      html  css  js  c++  java
  • flask入门

    1.flask介绍 

      Flask是Python编写的一款轻量级Web应用框架。其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2。
      Flask使用 BSD 授权。其中两个环境依赖是Werkzeug和jinja2,这意味着它不需要依赖外部库,正因如此,我们将其称为轻量级框架。
      Werkzeug是一个WSGI工具集,作为一个 Web 框架的底层库,它封装好了很多 Web 框架的东西,例如 Request,Response 等。

    flask:

    1. 轻,短小精悍
    2. 快,三行代码开启服务
    3. 自带组件少,大多数来源第三方,flask-admin,flask-session
    4. flask大版本更新,组件更新速度慢

    django:

    1. 大而全,admin,models,Form,中间件
    2. 一个框架解决所有问题
    3. 一旦启动,所有资源全部加载
    4. 太大,结构复杂
    5. 所有组件都有django组件自身控制 

    tornado:

    1. 原生websocket
    2. 异步IO
    3. 非阻塞
    4. 几乎无三方及原生组件,连session都不支持

    flask常用扩展包

    Flask-SQLalchemy:操作数据库;
    Flask-script:插入脚本;
    Flask-migrate:管理迁移数据库;
    Flask-Session:Session存储方式指定;
    Flask-WTF:表单;
    Flask-Mail:邮件;
    Flask-Bable:提供国际化和本地化支持,翻译;
    Flask-Login:认证用户状态;
    Flask-OpenID:认证;
    Flask-RESTful:开发REST API的工具;
    Flask-Bootstrap:集成前端Twitter Bootstrap框架;
    Flask-Moment:本地化日期和时间;
    Flask-Admin:简单而可扩展的管理接口的框架

    2.开启flask

    2.1简单运行  ----->(先通过终端安装flask(版本号1.0.2))

    尝试运行:

    from flask import Flask
    
    app = Flask(__name__)  # 模块名称将会作为单独应用启动还是作为模块启动而有不同,只有这么起名,Flask才知道去哪里找模板,静态文件等
    @app.route("/")    # 使用route装饰器告诉Flask什么样的URL可以出发我们的视图函数
    def index():
        return "hello flask"

    # 这里常规写法还是加上if __name__ == "__main__"比较好,确保服务器只会在该脚本被python解释器执行的时候运行,而非作为模板导入的时候  

    效果

    3.render_template,redirect,HttpResponse,jsonify

    3.1 HttpResponse

    @app.route("/")
    def index():
        return "hello flask"    # 这里的return等同HttpResponse,直接返回字符串

    3.2 Redirect 

     和django中的一样,用于重定向

    from flask import Flask,redirect
    
    app = Flask(__name__)
    
    @app.route('/index')
    def index():
        return redirect("/")    # 跳转到根目录页面
    
    
    @app.route('/')
    def main():
        return "ok"
    
    if __name__ == "__main__":
        app.run("0.0.0.0",5005,debug=True)

    当我们访问url:  http://127.0.0.1:5000/index的时候,它会触发redirect("/")跳转到该地址,并触发对应的视图函数main

    3.3 render_template

      这里的render_template等同我们django中的render,不过在此我们需要创建一个html标签来接收

      这里需要创建一个在同级目录下创建一个templates文件(必须叫它,源码规定),用于存放我们的html标签

    from flask import Flask,render_template
    
    app = Flask(__name__)
    
    @app.route('/index')
    def index():
        return render_template("index.html")
    
    
    if __name__ == "__main__":
        app.run("0.0.0.0",5005,debug=True)

    说明:

      这里一般需要指定我们的templates路径,否则会飘黄,因为模板语言采用的是jinja2,而django采用的模板语言是django,我们需要进行设置,或者选择在setting中设置

    3.4 jsonify

      使用 Flask 写一个接口时候需要给客户端返回 JSON 数据,在 Flask 中可以直接使用 jsonify 生成一个 JSON 的响应

    from flask import Flask,jsonify
    app = Flask(__name__)
    
    # 返回JSON
    @app.route('/demo')
    def demo():
        json_dict = {
            "user_id": 10,
            "user_name": "laowang"
        }
        return jsonify(json_dict)
    
    if __name__=="__main__":
        app.run(debug=True)

    效果:

    # 不推荐使用 json.dumps 转成 JSON 字符串直接返回,因为返回的数据要符合 HTTP 协议规范,如果是 JSON 需要指定 content-type:application/json

    4. 关于request

    4.1 简单说明

     django的接口是依据uwsgi

     flask依赖一个实现wsgi协议的模块:werkzeug

     flask使用了werkzeug库中的MapRule来管理url与处理函数映射关系

     它可以作为一个 Web 框架的底层库,因为它封装好了很多 Web 框架的东西,例如 Request,Response 等等。

    from werkzeug.wrappers import Request, Response
    from werkzeug.serving import run_simple
    
    @Request.application
    def hello(request):
        print(request)      # <Request 'http://localhost:4000/' [GET]>
        print(request.method)       # GET
        print(request.url)      # http://localhost:4000/
        print(dir(request))     # 获取所有的方法
        return Response('Hello World!')
    
    if __name__ == '__main__':
        run_simple('localhost', 4000, hello)    # 执行该函数

    4.2 request下常用参数说明:

    request.method  
    # 前端用什么方式提交,常见是GET和POST
    
    request.form   
     # Form表单中传递过来的值使用 request.form 中拿到,打印request.form,值 ImmutableMultiDict([('user', 'learning'), ('pwd', '666')]),可看做成字典
      
    request.args    
    # url中传递的参数,即get请求中问号结尾后面的数据,类似django中的request.get,原始样式ImmutableMultiDict([('id', '2')])
    
    reques.values    
    # 获取所有参数,打印值 CombinedMultiDict([ImmutableMultiDict([('id', '1'), ('age', '20')]), ImmutableMultiDict([('user', 'learning'), ('pwd', '666')])])
    
    # 它可以通过打印 request.values.to_dict() 把值全部转化成字典形式
    
    # 从这里可以看出,有些情况下url中的key和form中的key会重名,此时会出现覆盖的情况,生产环境中一定要注意该情况(form中的key会覆盖url中的key)
    
    request.cookies   
    # 存在浏览器端的字符串儿也会一起带过来
    
    request.heads   
    # 获取请求的请求头
    
    request.data    
    # 将处理不了的数据类型转换成json存入data中  # 数据类型参考手册
    
    request.files    
    # 遇到文件上传,request.files 里面存的是你上传的文件
    
    request.path
    # 获取当前的url路径
    
    request.url
    # 当前url的全部路径
    
    request.script_root
    # 当前url路径的上一级路径
    
    request.url_root
    # 当前url的路径的上一级全部路径
    
    request.json
    # 如果在请求中写入了 "application/json" 使用 request.json 则返回json解析数据, 否则返回 None

    获取参数request.args的使用

    from flask import Flask,request
    app = Flask(__name__)
    
    @app.route('/flask/')
    def index():
        id = request.args.get('id')
        return '获取id是%s'% id
    
    if __name__ == "__main__":
        app.run(debug=True)

    效果

    request.file上传文件说明

    1. 一个 <form> 标签被标记有 enctype=multipart/form-data ,并且在里面包含一个 <input type=file> 标签。
    2. 服务端应用通过请求对象上的 files 字典访问文件。
    3. 使用文件的 save() 方法将文件永久地保存在文件系统上的某处。

     login.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h4>欢迎登陆</h4>
    <form action="/req" method="post" enctype="multipart/form-data">
        <p>
            <input type="file" name="file">
        </p>
        <input type="submit" value="提交">
    </form>
    </body>
    </html>

     # 前端页面必须设置enctype="multipart/form-data",否则提交时会报错

    app.py

    from flask import Flask  
    from flask import render_template  
    from flask import request  
    
    app = Flask(__name__)
    
    @app.route("/login")
    def login():
        return render_template("login.html")
    
    
    @app.route("/req",methods=["POST","GET"])
    def home():
        print(request.files)  # ImmutableMultiDict([('file', <FileStorage: '5.jpg' ('image/jpeg')>)])
        print(request.files["file"])  # <FileStorage: '5.jpg' ('image/jpeg')>
        my_file = request.files["file"]
        print(type(my_file))    # <class 'werkzeug.datastructures.FileStorage'>
        my_file.save("aa.jpg")      # 这里写的有问题,图片过来名字就换了,而且还需判断发送的文件类型
        return "ok"
    
    if __name__ == '__main__':
        app.run(port=5990, debug=True)

    # 这里写的文件保存这里写的比较粗略,详细介绍可参考源码说明

    5. 关于response

    视图函数中可以返回的类型:

      字符串,返回的字符串其实底层将这个字符串包装成了一个‘Response’对象

      元祖,和字符串一样

      response及其子类

    如何返回其他类型呢??这就需要我们自定义一个Response对象,他继承自Response,套用了多继承下BaseResponse的force_type方法

    from flask import Flask,url_for,Response,jsonify
    
    app = Flask(__name__)
    
    class JsonResponse(Response):
    
        @classmethod
        def force_type(cls, response, environ=None):
            '''
            这个方法只有视图函数返回非字符、非元祖、非Response对象才会调用
            '''
            #把字典转换成json
            if isinstance(response,dict):
                #jsonify将字典转换成json对象,还将该对象包装成了一个Response对象
                response = jsonify(response)
            return super(JsonResponse, cls).force_type(response,environ)
    
    app.response_class = JsonResponse   # 指定app.response_class为你自定义的Response对象
    
    @app.route('/list1/')
    def list1():
        return Response('list1')  #合法对象,可以直接返回
    
    @app.route('/list3/')
    def list3():
        return {'username':'learning','age':22}   #返回的是非字符非元祖非Response对象,执行force_type方法
    
    if __name__ == "__main__":
        app.run(port=5225,debug=True)

    效果

    6. 关于__name__的说明

    app1下:
    import app2
    print("这在app1中",__name__)
    
    
    app2下:
    print("app2",__name__)

    这里我在app1下打印:

     # 这里需要强调的是,如果是在自己的文件下,__name__就是__main__,如果是从其他文件导入进来,则__name__就是它的文件名

  • 相关阅读:
    图片轮播切换
    php用get_meta_tags轻松获取网页的meta信息
    PHP创建桌面快捷方式实例
    php 获取网站根目录的写法
    php mkdir 创建多级目录实例代码
    php计算剩余时间的自定义函数
    php实现获取汉字的首字母实例
    PDO封装函数
    Struts动态表单(DynamicForm)
    [WPF]静态资源(StaticResource)和动态资源(DynamicResource)
  • 原文地址:https://www.cnblogs.com/LearningOnline/p/9590089.html
Copyright © 2011-2022 走看看