请求Request

请求对象

QueryDict 对象

QueryDict 对象是 django 中一种特殊类型的字典

里面可以存储 一对一类型的数据, 也可以存储 一对多类型的数据

这个对象一般用来存储浏览器传递过来的参数

我们可以默认把他看成是一个字典

但是它和一般的字典的不同之处在于:

  • 一键 ===> 一值: QueryDict 这个字典可以调用 get( ) 函数来获取.

  • 一键 ===> 多值: QueryDict 这个字典的获取方法:

    • 如果获取一个值: QueryDict.get( key ) 获取的是所有值的最后一个.
    • 如果获取多个值: QueryDict.getlist( key ) 获取这个键对应的所有值, 存放在列表中返回.

get( ):

根据一个 key 获取一个值

如果一个键同时拥有多个值将获取最后一个值

  # 使用格式: 
  QueryDict.get('键')
  # 或可写为: 
  QueryDict['键']

  # 例如
  QueryDict.get('a')  # 获取 a 所对应的一个值.

getlist( ):

根据一个 key 获取多个值

根据键获取对应的值,值以列表返回

可以获取指定键的所有值, 如果键不存在则返回空列表 [ ]

  # 使用格式: 
  QueryDict.getlist('键')

  # 例如
  QueryDict.getlist('a')  # 获取 a 所对应的所有值.

前端传参的四种方式

查询字符串传参 ( QueryString )

什么是查询字符串?

 

简单理解:

url : http://www.itcast.cn:80/users/index/?a=1&b=2&c=3#id=123

url 地址中以 ? 开始,直到 # 结束的部分, 我们统称为: 查询字符串( QueryString )

获取请求路径中的查询字符串参数(形如 ?k1=v1&k2=v2 )

 

获取查询字符串传递的参数

可以通过 request.GET 属性获取,这个方法返回 QueryDict 对象。

// 前端发送请求: 
$.ajax({
    url:'http://127.0.0.1:8000/reqresp/qs/?a=1&b=2&a=3',
    type:'get',
    dataType:'json'
})
.done(function(data){
    console.log(data)     // 打印: OK
})
.fail(function(error){
    console.log(error)
})
# python 部分接收发送的参数并打印: 
# 视图函数
def qs(request):
    # 获取查询字符串参数
    a = request.GET.get('a')
    b = request.GET.get('b')
    alist = request.GET.getlist('a')
    # 打印
    print(a)  # 3
    print(b)  # 2
    print(alist)  # ['1', '3']
    # 返回响应对象
    return HttpResponse('OK')

重要:

查询字符串不区分请求方式,即假使客户端进行 POST 方式的请求,依然可以通过 request.GET 获取请求中的查询字符串数据。

注意:

  • 这里的 request.GET 指的不是发送 ajax 用的 get 方法, 而是指从 url 的查询字符串中获取参数
  • 同理: request.POST 指的也不是 ajax 用的 post 方法,而是我们从请求体中获取的参数
  • 通过上面大家就能明白: GET 和 POST 这里指的都是获取参数的位置, 而不是我们以前说的 get 请求和 post 请求.
总结:
  • 如果前端传的参数是字符串类型, 可以通过 request.GET 来获取
  • 通过 request.GET 获取的是 QueryDict 类型
  • 我们可以通过 QueryDict 的 get( ) 和 getlist( ) 方法来获取对应的数据.

通过 URL 路径传参

在定义路由 URL 时,可以使用正则表达式提取参数的方法从 URL 中获取请求参数,Django 会将提取的参数直接传递到视图的传入参数中。

  • 未命名参数按定义顺序传递
子路由则应该这样写:
re_path(r'^weather/([a-z]+)/(\d{4})/$', views.weather),

对应的视图部分( views.py ):

def weather(request, city, year):
    '''定义weather函数, 接收路径参数'''
    print('city=%s' % city)
    print('year=%s' % year)
    return HttpResponse('OK')
  • 命名参数按名字传递
子路由则应该这样写:
这里用到了python高级知识: 正则分组命名.
re_path(r'^weather/(?P<city>[a-z]+)/(?P<year>\d{4})/$', views.weather),

对应的视图部分( views.py ):

起名字的话, 我们在接收参数时, 可以更换参数位置.
  def weather(request, year, city):
      '''定义weather函数, 接收路径参数'''
      print('city=%s' % city)
      print('year=%s' % year)
      return HttpResponse('OK')

总结:

  • 路径传参是前端发送参数的一种常用形式
  • 把参数伪装成路径, 传递到后端
  • 路径传参会在路径匹配的时候进行正则校验
  • 路径传参分为未命名参数和命名参数
  • 命名参数就是分别给参数起一个名字
  • 未命名参数就是不给参数起名字

非表单类型传值 ( Non-Form Data )

非表单类型传值的方式:

非表单类型的请求体数据,Django 无法自动解析

可以通过 request.body 属性获取最原始的请求体数据,自己按照请求体格式( JSON、XML 等)进行解析。

其中: request.body 返回 bytes 类型。

# 获取方式: 
request.body   # 得到的是 bytes 类型数据

# 可以通过 decode() 函数: 将 bytes 转为 str
request.body.decode()

# 可以通过 json.loads() 函数把 str 转为 dict 
json.loads(request.body.decode())

例如:

要获取请求体中的如下 JSON 数据

{"a": 1, "b": 2}

可以进行如下方法操作:

import json

def get_body_json(request):
    '''定义一个函数,接收json数据'''
    # 获取 json 类型数据: 
    json_bytes = request.body
    # 将 bytes 类型转为 str
    json_str = json_bytes.decode()
    # 将 str 转为 dict 
    dict = json.loads(json_str)

    print(dict.get('a'))  # 1
    print(dict.get('b'))  # 2
    return HttpResponse('OK')

总结:

  • 如果前端传递的是 json 类型的数据, 可以通过 request.body 类获取
  • 获取到的数据是 bytes 类型, 所以我们需要将其解码为 str 类型
  • 另外, 转为 str 后, 如果需要转为 dict, 则需要调用 json.loads( ) 函数

请求对象中的请求头信息

获取请求头数据

可以通过 request.META 属性获取请求头中的数据 request.META 为字典类型

这里需要注意一点是: 我们平常见到的请求头是这样的:

POST /reqresp/req/ HTTP/1.1
Host: 127.0.0.1:8000
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
Postman-Token: dd531a45-7518-1e8f-63a5-be03ed593471

a=1&b=2&a=3

但是我们通过 request.META 获取的时候,需要使用如下所示的用法:

CONTENT_LENGTH – The length of the request body (as a string).
CONTENT_TYPE – The MIME type of the request body.
HTTP_ACCEPT – Acceptable content types for the response.
HTTP_ACCEPT_ENCODING – Acceptable encodings for the response.
HTTP_ACCEPT_LANGUAGE – Acceptable languages for the response.
HTTP_HOST – The HTTP Host header sent by the client.
HTTP_REFERER – The referring page, if any.
HTTP_USER_AGENT – The client’s user-agent string.
QUERY_STRING – The query string, as a single (unparsed) string.
REMOTE_ADDR – The IP address of the client.
REMOTE_HOST – The hostname of the client.
REMOTE_USER – The user authenticated by the Web server, if any.
REQUEST_METHOD – A string such as "GET" or "POST".
SERVER_NAME – The hostname of the server.
SERVER_PORT – The port of the server (as a string).

具体使用如:

def get_headers(request):
    # 使用字典的方式获取请求头内部的数据
    print(request.META['CONTENT_TYPE'])
    # 返回
    return HttpResponse('OK')

总结:

  • 通过 request.META 属性我们可以获取请求对象的所有请求头信息
  • request.META 是一个字典
  • 从 request.META 中获取数据时, key 值需要大写

 

上一篇:QueryDIct对象


下一篇:Django边学边记—视图