我想写一个Django视图,根据请求提供变体内容。例如,对于“text / xml”,提供XML,“text / json”,提供JSON等。有没有办法从请求对象中确定这个?像这样的东西会很棒:
def process(request):
if request.type == "text/xml":
pass
elif request.type == "text/json":
pass
else:
pass
HttpRequest
上有属性吗?
答案 0 :(得分:19)
'Content-Type'标头表示HTTP请求中的媒体类型发送。这用于具有内容(POST,PUT)的请求。
'Content-Type'不应用于表示首选响应格式,'Accept'标题用于此目的。要在Django中访问它,请使用:HttpRequest.META.get('HTTP_ACCEPT')
答案 1 :(得分:15)
HttpRequest.META
,更具体地说是HttpRequest.META.get('HTTP_ACCEPT')
- 而不是前面提到的 HttpRequest.META.get('CONTENT_TYPE')
答案 2 :(得分:3)
在django 1.10中,您现在可以使用request.content_type
,如their doc
答案 3 :(得分:2)
如其他答案中所述,此信息位于Accept
请求标头中。请求中提供HttpRequest.META['HTTP_ACCEPT']
。
但是,不仅有一个请求的内容类型,并且此标头通常是已接受/首选内容类型的列表。这个列表可能有点烦人,无法正确利用。这是一个完成工作的功能:
import re
def get_accepted_content_types(request):
def qualify(x):
parts = x.split(';', 1)
if len(parts) == 2:
match = re.match(r'(^|;)q=(0(\.\d{,3})?|1(\.0{,3})?)(;|$)',
parts[1])
if match:
return parts[0], float(match.group(2))
return parts[0], 1
raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',')
qualified_content_types = map(qualify, raw_content_types)
return (x[0] for x in sorted(qualified_content_types,
key=lambda x: x[1], reverse=True))
例如,如果request.META['HTTP_ACCEPT']
等于"text/html;q=0.9,application/xhtml+xml,application/xml;q=0.8,*/*;q=0.7"
。这将返回:['application/xhtml+xml', 'text/html', 'application/xml', '*/*']
(实际上不是,因为它返回一个生成器)。
然后,您可以遍历结果列表,以选择您知道如何正确响应的第一个内容类型。
请注意,此功能适用于大多数情况,但不处理q=0
这样的情况,这意味着“不接受”。
来源:HTTP Accept header specification和Quality Values specification