Django中的Request和Response对象

这篇文章我们来学习下Django中的Request对象和Response对象。

HTTP请求与Django Request对象

我们看下一个HTTP请求中有哪些需要我们注意的:

请求方法、headers、请求参数、cookies、请求端信息

上面这些在对应于Django Request对象的什么:

请求方法 – Request对象的method属性

客户端信息 – Request对象的META属性

Cookies – Request对象的COOKIES属性

请求参数 – Request对象中的QueryDict

1
2
3
4
5
6
def helloworld(request):
print('request method: ', request.method)
print('request META: ', request.META)
print('request cookies: ', request.COOKIES)
print('request QueryDict: ', request.GET)
return HttpResponse(content='Hello Django Response', status=200)
HTTP应答与Django Response对象

在HTTP应答中我们需要关注的是 状态码、应答内容、内容格式

状态码 – Response对象的status属性

应答内容 – Response对象的content属性

延伸的Response子类 – (JsonResponse、FileResponse)根据返回类型不同,选择不同的Response

1
2
3
4
5
6
return HttpResponse(content='Hello Django Response', status=201)

m = {
"message": "Hello Django Response"
}
return JsonResponse(data=m, safe=False, status=200)

注意:在 JsonResponse 中 内容属性是 data 而不是 content

关于safe属性:

如果safe参数设置为False,则可以是任何可JSON 序列化的对象。

如果设置为True则只能是Python的Dict对象类型。

我们看下的源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class JsonResponse(HttpResponse):
"""
An HTTP response class that consumes data to be serialized to JSON.

:param data: Data to be dumped into json. By default only ``dict`` objects
are allowed to be passed due to a security flaw before EcmaScript 5. See
the ``safe`` parameter for more information.
:param encoder: Should be a json encoder class. Defaults to
``django.core.serializers.json.DjangoJSONEncoder``.
:param safe: Controls if only ``dict`` objects may be serialized. Defaults
to ``True``.
:param json_dumps_params: A dictionary of kwargs passed to json.dumps().
"""

def __init__(self, data, encoder=DjangoJSONEncoder, safe=True,
json_dumps_params=None, **kwargs):
if safe and not isinstance(data, dict):
raise TypeError(
'In order to allow non-dict objects to be serialized set the '
'safe parameter to False.'
)
if json_dumps_params is None:
json_dumps_params = {}
kwargs.setdefault('content_type', 'application/json')
data = json.dumps(data, cls=encoder, **json_dumps_params)
super().__init__(content=data, **kwargs)

序列化内部使用的还是jsondumps。当我们想自己写序列化类的时候,只需要指定

属性encoder为我们自己写的序列化类就好了。

类别 Flask 框架的 jsonfy

实战:实现天气查询应用

通过Request和Response我们来实现一个天气查询的接口

image-20190119135227337

首先我们注册一个 聚合数据 的账号。

根据接口文档我们写一个自己封装的天气查询接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import json
import requests


def weather(cityname):
"""
:param cityname: 城市名字
:return: 返回实况天气
"""
key = '2d8a555813b3f44e2f8466070a33f9f0' # 换成看官自己的
api = 'http://v.juhe.cn/weather/index'
query_url = f'{api}?cityname={cityname}&key={key}'

response = requests.get(url=query_url)

response_dict = dict()

json_data = json.loads(response.text)

if json_data['resultcode'] == '200':

result = json_data.get('result')
sk = result.get('sk')

response_dict['query_result'] = 1 # 查询接口
response_dict['temperature'] = sk.get('temp') # 当前温度
response_dict['wind_direction'] = sk.get('wind_direction') # 当前风向
response_dict['wind_strength'] = sk.get('wind_strength') # 当前风力
response_dict['humidity'] = sk.get('humidity') # 当前湿度
response_dict['time'] = sk.get('time') # 当前湿度

else:

response_dict = {
'query_result': 0
}

return response_dict

编写Django代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def weather(request):
if request.method == 'GET':
city = request.GET.get('city')
if city is None:
return JsonResponse(data={"message": "请输入查询的城市!"}, status=400)
weather_data = juhe.weather(city)
if weather_data['query_result']:
return JsonResponse(data=weather_data, status=200)
else:
return JsonResponse(data={"message": "Query weather error!"}, status=200)

elif request.method == 'POST':
received_body = request.body
received_body = json.loads(received_body)

cities = received_body.get('cities')
response_data = []
for city in cities:
weather_data = juhe.weather(city)
if weather_data['query_result']:
weather_data['city'] = city
response_data.append(weather_data)
return JsonResponse(data=response_data, safe=False, status=200)
知识就是财富
如果您觉得文章对您有帮助, 欢迎请我喝杯水!