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

  • 2019 年 10 月 8 日
  • 筆記

目录

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,文本,图片等)  # 不能识别的类型 下载处理 - 浏览器会下载

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代码  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 模板语言简单使用

#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框架参考手册

我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2ky0wzouug4kk

作 者:郭楷丰

出 处:https://www.cnblogs.com/guokaifeng/