Django 中间件如何处理请求和响应的内容协商?
Django 中间件可以用来处理请求和响应的内容协商,即根据请求头部的 Accept 字段和视图函数返回的数据类型,自动选择最合适的响应格式。下面是处理内容协商的中间件代码,以及如何使用:
from django.http import HttpResponse from django.utils.deprecation import MiddlewareMixin class ContentNegotiationMiddleware(MiddlewareMixin): def process_response(self, request, response): if response.exception or response.status_code != 200 or not hasattr(response, 'data'): return response # 根据请求头部获取客户端能接受的数据类型 accept_header = request.META.get('HTTP_ACCEPT', '') accept_format = self.get_accept_format(accept_header) # 如果客户端接受的是 JSON 格式,则将数据转换为 JSON 格式 if accept_format == 'json': response.content = json.dumps(response.data) response['Content-Type'] = 'application/json' # 如果客户端接受的是 XML 格式,则将数据转换为 XML 格式 elif accept_format == 'xml': response.content = xml.etree.ElementTree.tostring(response.data) response['Content-Type'] = 'application/xml' return response def get_accept_format(self, accept_header): """根据请求头部获取客户端能接受的数据类型""" if 'application/json' in accept_header: return 'json' elif 'application/xml' in accept_header: return 'xml' else: return 'json'
上面的中间件代码会根据客户端请求头部的 Accept 字段,自动选择最合适的响应格式,并将数据转换为对应格式的内容。使用该中间件只需要在 MIDDLEWARE
设置中添加该中间件的路径即可,例如:
MIDDLEWARE = [ # ... 'myapp.middleware.ContentNegotiationMiddleware', ]
现在,假设我们有一个视图函数 hello_world
,返回的数据类型为 Python 字典格式。如果客户端请求头部的 Accept 字段为 application/json
,则返回 JSON 格式的数据;如果请求头部为 application/xml
,则返回 XML 格式的数据。例如:
from django.http import JsonResponse from django.shortcuts import render def hello_world(request): data = {'message': 'Hello World!'} return JsonResponse(data)
在客户端发送请求时,可以设置请求头部的 Accept 字段来指定期望的响应格式:
$ curl -H 'Accept: application/json' 'http://example.com/hello' {"message": "Hello World!"} $ curl -H 'Accept: application/xml' 'http://example.com/hello' <?xml version="1.0" encoding="UTF-8"?> <root><message>Hello World!</message></root>
上面的代码演示了客户端发送不同格式的请求,然后服务器自动根据客户端请求头部自动选择最合适的响应格式。
相关文章