django请求与响应

目录

一、请求Request

利用HTTP协议向服务器传参有几种途径

Django中的QueryDict对象

[1> GET属性获取查询字符串Query String 参数](#1> GET属性获取查询字符串Query String 参数)

[2> POST属性 获取请求体参数](#2> POST属性 获取请求体参数)

[3> META属性 获取请求头数据](#3> META属性 获取请求头数据)

[4> 其他常用HttpRequest对象属性](#4> 其他常用HttpRequest对象属性)

二、响应Response

[1> HttpResponse](#1> HttpResponse)

[3> JsonResponse](#3> JsonResponse)


一、请求Request

利用HTTP协议向服务器传参有几种途径
  • 路径传参: 提取URL的特定部分,如/weather/beijing/2018,可以在服务器端的路由中用正则表达式截取参数;
  • 查询字符串传参: 查询字符串(query string),形如key1=value1&key2=value2;
  • **请求体传参:**请求体(body)中发送的数据,比如表单数据、json、xml;
  • **请求头传参:**在http报文的请求头(header)中传参。
Django中的QueryDict对象
  • QueryDict对象介绍

    复制代码
    QueryDict定义在django.http.QueryDict中; HttpRequest对象的属性GET、POST都是QueryDict类型的对象;与python字典不同,QueryDict类型的对象用来处理同一个键带有多个值的情况.
  • get() 方法

    根据键获取值, 如果一个键同时拥有多个值将获取最后一个值; 如果键不存在则返回None值,可以设置默认值进行后续处理

    复制代码
    dict.get('键',默认值)
    复制代码
    # 可简写为
    复制代码
    dict['键']
  • getlist() 方法

    根据键获取值,值以列表返回,可以获取指定键的所有值; 如果键不存在则返回空列表[],可以设置默认值进行后续处理

    复制代码
    dict.getlist('键',默认值)
1> GET属性获取查询字符串Query String 参数
  • GET属性说明

    复制代码
        获取请求路径中的查询字符串参数(形如 ?k1=v1&k2=v2 ),可以通过request.GET属性获取,返回QueryDict对象。
    复制代码
    注意: 查询字符串不区分请求方式,即使客户端进行POST方式的请求,依然可以通过request.GET获取请求中的查询字符串数据。
    主路由

    # 获取查询字符串路由
    path('qs/', views.query_string),
    视图





    from django.http import HttpResponse
    from django.views.decorators.csrf import csrf_exempt
    ​
    ​
    # 免除csrf校验
    @csrf_exempt
    def query_string(request):
        # 获取键对应的最后一个值
        a = request.GET.get('a')
        b = request.GET.get('b')
        # 获取键对应的所有值
        a_list = request.GET.getlist('a')
    ​
        print(f"a = {a}")
        print(f"b = {b}")
        print(f"a_list = {a_list}")
    ​
        return HttpResponse('query_string OK')
  • API测试 Apipost软件下载

    复制代码
    # 测试平台 ApiPost7
    复制代码
    GET请求  http://127.0.0.1:8080/qs/?a=1&b=3&a=10
    复制代码
    POST请求  http://127.0.0.1:8080/qs/?a=1&b=3&a=10
2> POST属性 获取请求体参数
复制代码
    请求体数据格式不固定,可以是表单类型字符串,可以是JSON字符串,也可以是XML字符串; 应区别对待。
复制代码
支持发送 请求体数据 的请求方式有: POST、PUT、PATCH、DELETE。
复制代码
​Django默认开启了CSRF防护,会对上述请求方式进行CSRF防护验证,在测试时可以关闭CSRF防护机制; 
复制代码
关闭方法: 
复制代码
1. 在 settings.py 配置文件 MIDDLEWARE 参数项中注释掉CSRF中间件CsrfViewMiddleware 全局生效
复制代码
2. 为视图函数单独添加 csrf_exempt装饰器 进行CSRF豁免 
  • 表单类型 Form Data

    复制代码
    前端发送的表单类型的请求体数据,可以通过request.POST属性获取,返回QueryDict对象。
    复制代码
    注意: request.POST只能用来获取POST方式的请求体表单数据。
    复制代码
    说明: 请求头中 Content-Type 为multipart/form-data(多媒体表单) 或者 application/x-www-form-urlencoded(简单表单) 即为表单类型请求 
  • 主路由

    复制代码
      # 获取表单数据路由
      path('form/', views.get_form),
    
  • templates 模板文件夹中创建模版文件 form.html

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>用户信息收集表</title>
      </head>
      <body>
          <form action="/form/" method="post" enctype="multipart/form-data">
              <p>
                  用户名: <input type="text" name="user"> <br>
              </p>
              <p>
                  密&emsp;码: <input type="password" name="pwd"> <br>
              </p>
              <p>
                  爱&emsp;好:
                  <input type="checkbox" name="hobby" value="game"> 游戏
                  <input type="checkbox" name="hobby" value="study"> 学习
              </p>
              <p>
                  文件上传: <input type="file" name="file1">
              </p>
              <p>
                  <input type="submit" value="提交">
              </p>
      
          </form>
      </body>
      </html>
    
  • 视图

    import os
      
      from django.http import HttpResponse
      from django.shortcuts import render
      from django.views.decorators.csrf import csrf_exempt
      # 导入配置对象
      from django.conf import settings
      
      @csrf_exempt
      def get_form(request):
          # 处理get请求 返回表单页面
          if request.method == "GET":
              return render(request, "form.html")
      
          # 处理post请求 接收表单数据
          user = request.POST.get("user")
          pwd = request.POST.get("pwd")
          hobby = request.POST.getlist("hobby")
          upload_file = request.FILES.get("file1")
      
          print(f"user: {user}")
          print(f"pwd: {pwd}")
          print(f"hobby: {hobby}")
      
          if upload_file:
              file_save_path = os.path.join(settings.MEDIA_ROOT, upload_file.name)
              with open(file_save_path, "wb") as wf:
                  # 分块写入文件数据
                  for chunk in upload_file.chunks():
                      wf.write(chunk)
      
          return HttpResponse('get_form OK')
    

    配置文件 settings.py
    *

      MEDIA_ROOT = os.path.join(BASE_DIR, 'upload_media')
    

    测试
    *

      # 获取表单页面
      GET  http://127.0.0.1:8080/form/
      # 填写表单并提交表单数据, 查看接收数据和文件
    
  • 非表单类型 Non-Form Data

    复制代码
    非表单类型的请求体数据Django无法自动解析,可以通过request.body属性获取最原始的请求体数据,自己按照请求体数据格式(JSON、XML等)进行解析。(注意:request.body返回bytes类型。)
    复制代码
    例如: 要获取请求体中的如下JSON格式数据可以按如下步骤提取数据: 
    复制代码
    {"a": 1, "b": 2}
    • 主路由

      # 获取非表单数据路由
      path('nonForm/', views.get_non_form),
      
    • 视图

      import json
      ​
      @csrf_exempt
      def get_non_form(request):
          json_str = request.body
          # python3.6 及以上版本无需执行解码操作,json.loads可以直接处理二进制数据
          json_str = json_str.decode()  
          req_data = json.loads(json_str)
      ​
          print(f"req_data = {req_data}")
          print(f"a = {req_data['a']}")
          print(f"b = {req_data['b']}")
      ​
          return HttpResponse('get_non_form OK')
      

      测试

    复制代码
    # 测试平台 ApiPost7
    复制代码
    # 提交非表单数据(这里测试json数据)
    复制代码
    POST  http://127.0.0.1:8080/nonForm/
3> META属性 获取请求头数据
复制代码
可以通过request.META属性获取请求头headers中的数据,request.META为字典类型。
  • 常见的请求头如:

    • CONTENT_LENGTH -- 请求体长度.
    • CONTENT_TYPE -- 内容的数据类型。同附加信息的查询一起使用,如 HTTP 查询 GET、 POST 和 PUT.
    • HTTP_ACCEPT -- 浏览器支持的 MIME 类型.
    • HTTP_ACCEPT_ENCODING -- 浏览器支持的压缩编码.
    • HTTP_ACCEPT_LANGUAGE -- 浏览器支持的语言.
    • HTTP_HOST -- 服务器端IP及端口.
    • HTTP_REFERER -- 用于告知服务器是从哪个页面链接过来的.
    • HTTP_USER_AGENT -- 使用的用户代理 域名.
    • QUERY_STRING -- 查询解析输入并在运算符周围分割文本.
    • REMOTE_ADDR -- 客户端IP.
    • REMOTE_HOST -- 发出请求的主机名称。如果服务器无此信息,它将设置为空的 MOTE_ADDR 变量.
    • REMOTE_USER -- 服务器认证后的用户.
    • REQUEST_METHOD -- 该方法用于提出请求。相当于用于 HTTP 的 GET、HEAD、POST 等等.
    • SERVER_NAME -- 出现在自引用 UAL 中的服务器主机名、DNS 化名或 IP 地址.
    • SERVER_PORT -- 发送请求的端口号.
  • 具体使用:

    • 主路由

      # 获取请求头数据路由
      path('header/', views.get_request_header),
      
    • 视图

      @csrf_exempt
      def get_request_header(request):
          meta = request.META
          print(f"请求体长度: {meta['CONTENT_LENGTH']}")
          print(f"服务器端IP及端口: {meta['HTTP_HOST']}")
          print(f"内容的数据类型: {meta['CONTENT_TYPE']}")
      ​
          print("\nHttpRequest的其他对象属性:")
          print(f"请求方法: {request.method}")
          print(f"用户对象: {request.user}")
          print(f"完整路径: {request.path}")
          print(f"提交的数据的编码方式: {request.encoding}")
          print(f"coolies: {request.COOKIES}")
          print(f"session: {request.session}")
          print(f"是否为ajax请求: {request.is_ajax()}")
      ​
          return HttpResponse('get_request_header OK')
      
      复制代码
    • 测试

      复制代码
      # 测试平台 ApiPost7
      复制代码
      GET  http://127.0.0.1:8080/header/
      复制代码
      POST  http://127.0.0.1:8080/header/
4> 其他常用HttpRequest对象属性
  • method:一个字符串,表示请求使用的HTTP方法,常用值包括:'GET'、'POST'。

  • user :请求的用户对象。

  • path:一个字符串,表示请求的页面的完整路径,不包含域名和参数部分。

  • get_full_path(): 获取请求的页面的完整路径,不包含域名但是包含查询参数部分。

  • encoding:一个字符串,表示提交的数据的编码方式。

    • 如果为None则表示使用浏览器的默认设置,一般为utf-8。
    • 这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的encoding值。
  • GET: 一个类似于字典的对象,包含get请求方式的所有参数

  • POST: 一个类似于字典的对象,包含post请求方式的所有参数

  • FILES:一个类似于字典的对象,包含所有的上传文件。

  • COOKIES: 一个标准的Python字典,包含所有的cookie,键和值都为字符串

  • session: 一个既可读又可写的类似于字典的对象,表示当前的会话,只有当Django启用会话的支持时才可用

  • is_ajax( ): 如果请求是通过XMLHttpRequest发起的,则返回True

  • resolver_match: 当前路由匹配成功的路由对象(url_name属性可以得到当前匹配到的路由名)

二、响应Response

复制代码

视图在接收请求并处理后,必须返回HttpResponse对象或子对象。HttpRequest对象由Django创建,HttpResponse对象由开发人员创建。

1> HttpResponse
  • 可以使用 django.http.HttpResponse 来构造响应对象。

    复制代码
    HttpResponse(content=响应体, content_type=响应体数据类型, status=状态码)
  • 也可通过 HttpResponse 对象属性来设置响应体、状态码:

    • content:表示返回的内容。
    • status_code:返回的HTTP响应状态码。
    • charset :表示response采用的编码字符集,字符串类型
  • 可以直接将HttpResponse对象当做字典,使用键值对赋值的方式设置响应头信息:

    复制代码
    response = HttpResponse()
    复制代码
    # 自定义响应头 Platform, 值为xx
    复制代码
    response['Platform'] = 'xx'
  • 使用示例:

    • 主路由

      # 设置响应路由
      
      path('response/', views.set_response),
      
    • 视图

      @csrf_exempt
      def set_response(request):
          # 通过 HttpResponse 构造响应对象
          # return HttpResponse(content='xxxx', status=200)
          
          # 通过 HttpResponse 对象属性设置响应体、状态码、响应头
          response = HttpResponse()
          response.content = 'xxxx'
          response.status_code = 200
          response['Platform'] = 'xx
          return response
      
    • 测试

      复制代码
      # 测试平台 ApiPost7
      复制代码
      POST  http://127.0.0.1:8080/response/2> HttpResponse 的子类
    • Django提供了一系列HttpResponse的子类,可以快速设置状态码

      • HttpResponseRedirect 301
      • HttpResponsePermanentRedirect 302
      • HttpResponseNotModified 304
      • HttpResponseBadRequest 400
      • HttpResponseNotFound 404
      • HttpResponseForbidden 403
      • HttpResponseNotAllowed 405
      • HttpResponseGone 410
      • HttpResponseServerError 500
3> JsonResponse
  • 若要返回json数据,可以使用JsonResponse来构造响应对象,作用:

    • 帮助我们将数据转换为json字符串

    • 设置响应头**Content-Type** 为 application/json

      from django.http import JsonResponse
      ​
      def demo_view(request):
          return JsonResponse({'城市': 'beijing', 'subject': 'python'}, json_dumps_params={'ensure_ascii': False})
      
相关推荐
幽兰的天空20 分钟前
Python 中的模式匹配:深入了解 match 语句
开发语言·python
远歌已逝1 小时前
维护在线重做日志(二)
数据库·oracle
qq_433099402 小时前
Ubuntu20.04从零安装IsaacSim/IsaacLab
数据库
Dlwyz2 小时前
redis-击穿、穿透、雪崩
数据库·redis·缓存
网易独家音乐人Mike Zhou4 小时前
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
c语言·python·单片机·物联网·算法·嵌入式·iot
安静读书4 小时前
Python解析视频FPS(帧率)、分辨率信息
python·opencv·音视频
工业甲酰苯胺4 小时前
Redis性能优化的18招
数据库·redis·性能优化
没书读了5 小时前
ssm框架-spring-spring声明式事务
java·数据库·spring
小二·5 小时前
java基础面试题笔记(基础篇)
java·笔记·python
i道i6 小时前
MySQL win安装 和 pymysql使用示例
数据库·mysql