• Flask框架 请求与响应 & 模板语法


    Flask框架 请求与响应 & 模板语法

    简单了解Flask框架

    	Flask是一个轻量级的可定制框架,使用Python语言编写,较其他同类型框架更为灵活、轻便、安全且容易上手。
    它可以很好地结合MVC模式进行开发,开发人员分工合作,小型团队在短时间内就可以完成功能丰富的中小型网站或Web服务的实现。
    另外,Flask还有很强的定制性,用户可以根据自己的需求来添加相应的功能,在保持核心功能简单的同时实现功能的丰富与扩展,
    其强大的插件库可以让用户实现个性化的网站定制,开发出功能强大的网站。 
    
    #安装Flask 
    - pip3 install Flask - 1.1.1
    
    Flask库文件(安装Flask时自动安装)
        - Jinja2 模板渲染库
        - MarkupSafe 返回安全标签 只要Flask 返回模板或者标签时都会依赖MarkupSafe
        - Werkzeug 德文“工具” == uWSGI 底层是 WSGI Flask项目启动都是基于Werkzeug
    

    Flask 框架 与 Django 框架对比

    Django 框架
    - 原生组件非常丰富       教科书式框架
    - Django.Model - ORM    面向对象操作数据库
    - Django.Form           Form组件
    - Django.ModelForm      ModelForm
    - Django.Session Model  Session
    - Admin CsrfToken       跨站请求伪造 
    
    Django框架(缺点) 加载项巨大 资源浪费
    Django框架 适合大型,密集型项目
    
    Flask Web框架 - 
    Flask 非常短小精悍 - 精简到只有一个 Session
    Flask 第三方组件 非常全
    
    Flask框架(缺点) 第三方组件 - 运行稳定性相对较差
    Flask框架 适合小型,API服务类项目		
    

    简单使用Flask提供服务

    # 三行启动Flask 提供服务
    from flask import Flask
    app = Flask(__name__)
    app.run()
    #访问一下看看效果
    

    # 启动Flask 提供服务,访问返回页面,"HelloWorld"
    from flask import Flask  # 导入Flask 类创建Flask应用对象
    app = Flask(__name__)  # app = application
    
    @app.route("/index")  # 为 Flask 应用对象增加路由
    def index():  # 与路由绑定的视图函数 视图函数名尽可能保持唯一 
        return "HelloWorld"  # “” 相当于 Django 中的 HttpResponse
    
    if __name__ == '__main__':  # 当前文件处于脚本状态时运行如下代码
        app.run()  # 启动Flask 应用
        
    #访问一下看看效果    
    

    Flask 中的 Response(响应)

    return "字符"

    @app.route("/index")  
    def index(): 
        return "HelloWorld"  # "HelloWorld" 相当于 Django中的HttpResponse返回响应 (效果如上图)
    

    render_template("HTML文件")

    #html代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>郭楷丰</title>
    </head>
    <body>
    <h1>你好</h1>
    </body>
    </html>
    
    #python代码 
    from flask import Flask, render_template
    
    app = Flask(__name__)
    
    @app.route("/home")
    def home():
        return render_template("home.html")  # 模板存放路径 templates
    
    if __name__ == '__main__':
        app.run()
    #访问一下看看效果   
    

    redirect("/home") 重定向

    from flask import Flask, render_template, redirect
    
    app = Flask(__name__)
    
    @app.route("/home")
    def home():
        return render_template("home.html")  
    
    @app.route("/re")
    def re():
        return redirect("/home")  #重定向到home
    
    if __name__ == '__main__':
        app.run()
    #访问一下看看效果      
    

    	小结:
        # 3xx HTTP status 
    	# 4xx 错误 客户端
    	# 5xx 错误 服务器
    	redirect("/home") 其实就是在ResponseHeaders 中加入了一个 Location:http://127.0.0.1:5000/home     
    

    send_file("文件路径") 返回文件

    #返回图片示例  代码
    #先准备一张图片 1.jpg
    from flask import Flask,send_file
    
    app = Flask(__name__)
    
    @app.route("/get_file")
    def get_file():
        return send_file("1.jpg")
    
    if __name__ == '__main__':
        app.run()    
        
    #访问一下试试看
    

    小结:
    # 打开并返回文件内容 自动识别文件类型 在ResponseHeaders中加入
    # Content-Type:文件类型 - *文件类型 是可以被客户端识别的文件类型(如MP4,MP3,文本,图片等)
    # 不能识别的类型 下载处理 - 浏览器会下载
    # 如果返回文件在其他文件下,需要加上路径信息 如: return send_file('tupian/cat.jpg')
    

    jsonify("字符串或数据类型")

    from flask import Flask, jsonify
    
    app = Flask(__name__)
    
    @app.route("/get_json")
    def get_json():
        d = {
            "name": "gkf"
        }
        return jsonify(d) 
    
    if __name__ == '__main__':
        app.run()
    
    #访问一下试试看    
    


    小结:
    jsonify("字符串或数据类型")  返回标准格式的JSON字符串
    # Content-Type:application/json == 标准格式
    # Flask 1.1.1 目前版本 支持return d 使用
    # return d  # 暂时不建议使用 兼容性差
    # 直接返回dict时 本质上在执行jsonify(d)
    
    jsonify()做了那些事
    # 1.打包JSON 序列化JSON字符串
    # 2.编写ResponseHeaders 加入 Content-Type:application/json
    
    应用场景:
    # API 接口 AJAX.post({username:123}){function(data){ obj = data }}
    

    Flask 中的 Request(请求)

    request.method(请求类型)

    #可以判断客户端的请求来做一些操作
    @app.route("/index")
    def index():
        print(request.method)  
        if request.method == 'GET': #如果是get请求,返回一个index.html文件
            return render_template("index.html")
    

    request.form (获取form提交数据)

    #html代码
    <form action="" method="post" enctype="multipart/form-data">
      <p>username: <input type="text" name="username"></p>
      <p><input type="file" name="my_file"></p>
      <input type="submit" value="登录">
    </form>
    #python代码
    @app.route('/login',methods=['GET','POST']) # methods=['GET','POST']必填,不然默认接受GET请求
    def login():
        if request.method == 'GET':
            return render_template('login.html')
    
        if request.method == 'POST':
            print(request.form.get("username")) #直接获取到username对应的值
            return redirect("/index")
    

    request.args (获取URL中的数据)

    #代码
    @app.route("/index")
    def index():
        if request.method == 'GET':
            print(request.args) #request.args.get('键') 来取值
            return render_template("index.html")
    

    request.url (请求地址)

    @app.route("/index")
    def index():
        if request.method == 'GET':
            print(request.url)
            return render_template("index.html")
    #当页面输入 http://127.0.0.1:5000/index 打印结果
    http://127.0.0.1:5000/index  
    #当页面输入 http://127.0.0.1:5000/index?郭楷丰=318 打印结果
    http://127.0.0.1:5000/index?郭楷丰=318
    

    request.url_charset (URL 编码方式)

    @app.route("/index")
    def index():
        if request.method == 'GET':
            print(request.url_charset)
            return render_template("index.html")
        
    #打印结果
    utf-8
    

    request.url_root (完整请求地址)

    # print(request.url_root) # 请求地址 完整请求地址 host
    
    @app.route("/index")
    def index():
        if request.method == 'GET':
            print(request.url_root)
            return render_template("index.html")
            
    #访问http://127.0.0.1:5000/index 打印结果
    http://127.0.0.1:5000/
    

    request.url_rule (请求路由地址)

     print(request.url_rule) # 请求路由地址(参数不会获取)
     
     #访问http://127.0.0.1:5000/index 打印结果
     /index
    

    request.values (接收所有请求中的数据)

    #接收所有(GET,POST)请求中的数据,包含了 URL 和 FormData 中的数据  
    #一般不使用这个 因为url中的参数和form表的的参数它都会获取,如果key值重名,会报错
    
    print(request.values)
    #访问http://127.0.0.1:5000/index?郭楷丰=318  打印结果
    CombinedMultiDict([ImmutableMultiDict([('郭楷丰', '318')]), ImmutableMultiDict([])])
    
    #to_dict 转为字典形式
    print(request.values.to_dict()) 
    #访问http://127.0.0.1:5000/index?郭楷丰=318  打印结果
    {'郭楷丰': '318'}
    

    request.files (获取页面提交的文件)

    @app.route("/login",methods=["GET","POST"]) #重新methods让它只接受"GET","POST"请求
    def login():
        if request.method == 'GET':
            return render_template('login.html')
    
        if request.method == 'POST':
            print(request.files)  
            print(request.files.get("my_file"))
            return redirect("/index")  
    
    #访问http://127.0.0.1:5000/login  并提交一个文件 执行结果
    ImmutableMultiDict([('my_file', <FileStorage: '1_副本.png' ('image/png')>)]) 
    <FileStorage: '1_副本.png' ('image/png')>  #获取文件名字
    

    request.files (保存文件示例)

    #upload.html文件代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>文件上传演示</title>
    </head>
    <body>
    <form action="" method="post" enctype="multipart/form-data">
      <p><input type="file" name="my_file"></p>
      <input type="submit" value="上传图片">
    </form>
    </body>
    </html>
    
    #python代码
    import os
    from flask import Flask, request, render_template
    
    app = Flask(__name__)
    app.secret_key = "!@#$%^&*()" #密钥(对session进行加密)
    app.debug = True #开启Debug模式 修改代码自动重启项目
    
    @app.route("/upload",methods=["GET","POST"])#重写methods只接收GET与POST请求
    def upload():
        if request.method == 'GET':
            return render_template('upload.html')
    
        if request.method == 'POST':
            dir_name = './美女图片'
            if not os.path.exists(dir_name):
                os.mkdir(dir_name)
            my_file = request.files.get("my_file")
            new_file = os.path.join(dir_name, my_file.filename)
            my_file.save(new_file)
            return "上传文件成功"
    
    if __name__ == '__main__':
        app.run()
    

    request (获取其他数据)

    # 获取其他数据
    # request.headers 请求头中的信息
    # request.cookies 请求中cookies的信息
    # request.path == request.url_rule  路由地址
    # request.host == "127.0.0.1:9527" 获取访问主机地址
    # request.host_url == "http://127.0.0.1:9527/" 路由地址
    
    # 特殊提交方式数据获取
    # request.json 获取Content-Type:application/json时提交的数据
    # Content-Type:application/json
    # request.data 获取 原始请求体中的数据 b""类型
    # Content-Type 无法被识别 或 不包含Form字眼
    

    Flask 模板语言简单使用

    模板引擎的作用就是读取并执行模板中的特殊语法标记,并根据传入的数据将变量替换为实际值,
    输出最终的HTML页面,这个过程被称为渲染(rendering)Flask默认使用的模板引擎是Jinja2
    
    Jinja2允许你在模板中使用大部分Python对象,比如字符串、列表、字典、元组、整型、浮点型、布尔值。
    它支持基本的运算符号(+、-、*、/等)、比较符号(比如==、!=等)、逻辑符号(and、or、not和括号)
    以及in、is、None和布尔值(True、False)
    
    注释       {#...#}
    表达式     字符串、变量、函数调用等  使用    {{  ...  }}
    逻辑相关   if判断,for循环           使用   {%  ...  %}
    
    # if 语法
    {% if 判断条件 %}
    	判断成功执行代码
    {% else %}
     	判断不成功执行代码
    {% endif %}
    
        
    # for语法
    {% for user in users %}
    	{{ user }}
    {% endfor %}
        
    {% for key, value in my_dict.items() %}
        <p>{{ key }}</p>
        <p>{{ value }}</p>
    {% endfor %}
    '''    Jinja2 for循环特殊变量
    oop.index     			循环迭代计数(从1开始)
    
    loop.index0   			循环迭代计数(从0开始)
    
    loop.revindex 			循环迭代倒序计数(从len开始,到1结束)
    
    loop.revindex0      	 循环迭代倒序计数(从len-1开始,到0结束)
    
    loop.first				是否为循环的第一个元素
    
    loop.last 				是否为循环的最后一个元素
    
    loop.length   			循环序列中元素的个数
    
    loop.cycle     			在给定的序列中轮循,如上例在”odd”和”even”两个值间轮循
    
    loop.depth    			当前循环在递归中的层级(从1开始)
    
    loop.depth0  			当前循环在递归中的层级(从0开始)	
    '''
    
    #python代码
    from flask import Flask, render_template
    
    #传给模板的数据
    STUDENT = {'name': 'Old', 'age': 38, 'gender': '中'} 
    STUDENT_LIST = [
        {'name': 'Old', 'age': 38, 'gender': '中'},
        {'name': 'Boy', 'age': 73, 'gender': '男'},
        {'name': 'EDU', 'age': 84, 'gender': '女'}
    ]
    STUDENT_DICT = {
        1: {'name': 'Old', 'age': 38, 'gender': '中'},
        2: {'name': 'Boy', 'age': 73, 'gender': '男'},
        3: {'name': 'EDU', 'age': 84, 'gender': '女'},
    }
    
    app = Flask(__name__)
    app.debug = True
    
    @app.template_global()
    def ab(a, b):
        return a + b
    
    @app.route("/stu")
    def stu():
        return render_template("stuinfo.html", stu_info=STUDENT, stu_list=STUDENT_LIST, stu_dict=STUDENT_DICT)
    
    if __name__ == '__main__':
        app.run()
    
    <!--stuinfo.html模板代码-->
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <title>学生信息</title>
      <style type='text/css'>
      p{
      background-color:#00ffaa;
      }
      </style>
    </head>
    <body>
    {{ stu_info }}
    <p>- - - - - - - -✂ - - - - - - - - - - - -分割线- - - - - - - - - - - -✂- - - - - - - -</p>
    <table border="1px">
      <tr>
        <td>name</td>
        <td>age</td>
        <td>gender</td>
      </tr>
      <tr>
        <td>{{ stu_info.name }}</td>
        <td>{{ stu_info.get("age") }}</td>
        <td>{{ stu_info["gender"] }}</td>
      </tr>
    </table>
    <p>- - - - - - - -✂ - - - - - - - - - - - -分割线- - - - - - - - - - - -✂- - - - - - - -</p>
    {{ stu_list }}
    <p>- - - - - - - -✂ - - - - - - - - - - - -分割线- - - - - - - - - - - -✂- - - - - - - -</p>
    <table border="1px">
      <tr>
        <td>name</td>
        <td>age</td>
        <td>gender</td>
      </tr>
      {% for stu in stu_list %}
        <tr>
          <td>{{ stu.name }}</td>
          <td>{{ stu.get("age") }}</td>
          <td>
            {% if  stu["gender"] != "男" and stu["gender"] != "女" %}
              李杰
            {% else %}
              {{ stu["gender"] }}
            {% endif %}
          </td>
        </tr>
      {% endfor %}
    </table>
    <p>- - - - - - - -✂ - - - - - - - - - - - -分割线- - - - - - - - - - - -✂- - - - - - - -</p>
    {{ stu_dict }}
    <p>- - - - - - - -✂ - - - - - - - - - - - -分割线- - - - - - - - - - - -✂- - - - - - - -</p>
    {% for foo in stu_dict %}
      {{ stu_dict[foo].get("name") }}
      {{ stu_dict[foo]["age"] }}
      {{ stu_dict[foo].gender }}
    {% endfor %}
    <p>- - - - - - - -✂ - - - - - - - - - - - -分割线- - - - - - - - - - - -✂- - - - - - - -</p>
    {% for foo,item in stu_dict.items() %}
      {{ foo }}
      {{ item.name }}
    {% endfor %}
    <p>- - - - - - - -✂ - - - - - - - - - - - -分割线- - - - - - - - - - - -✂- - - - - - - -</p>
    {{ ab(666,2) }}
    <p>- - - - - - - -✂ - - - - - - - - - - - -分割线- - - - - - - - - - - -✂- - - - - - - -</p>
    {% macro my_input(ty,na) %}
      请输入用户名 -> <input type="{{ ty }}" name="{{ na }}">
    {% endmacro %}
    <p>- - - - - - - -✂ - - - - - - - - - - - -分割线- - - - - - - - - - - -✂- - - - - - - -</p>
    <p>这就是我自己创造的input标签:{{ my_input("text","username") }} {{ my_input("password","pass") }} {{ my_input("file","myfile") }}</p>
    <p>- - - - - - - -✂ - - - - - - - - - - - -分割线- - - - - - - - - - - -✂- - - - - - - -</p>
    </body>
    </html>
    

    Flask框架参考手册

    作 者:郭楷丰
    声援博主:如果您觉得文章对您有帮助,可以点击文章右下角 推荐一下。您的鼓励是博主的最大动力!
    自 勉:生活,需要追求;梦想,需要坚持;生命,需要珍惜;但人生的路上,更需要坚强。带着感恩的心启程,学会爱,爱父母,爱自己,爱朋友,爱他人。
  • 相关阅读:
    Spring IoC
    Java软件安装
    Struts(一)
    Struts(二)
    Hibernate(六)
    Hibernate(五)
    Hibernate(二)
    Hibernate(四)
    Hibernate(三)
    Hibernate(一)
  • 原文地址:https://www.cnblogs.com/guokaifeng/p/11587311.html
Copyright © 2020-2023  润新知