确定请求的内容类型?

Naf*_*Kay 18 django django-views

我想写一个Django视图,根据请求提供变体内容.例如,对于"text/xml",提供XML,"text/json",提供JSON等.有没有办法从请求对象中确定这个?像这样的东西会很棒:

def process(request):
    if request.type == "text/xml":
        pass
    elif request.type == "text/json":
        pass
    else:
        pass
Run Code Online (Sandbox Code Playgroud)

这是否有财产HttpRequest

Jan*_*bel 19

'Content-Type'标头表示HTTP请求中的媒体类型发送.这用于具有内容(POST,PUT)的请求.

'Content-Type'不应用于表示首选响应格式,'Accept'标题用于此目的.要在Django中访问它,请使用:HttpRequest.META.get('HTTP_ACCEPT')

查看这些标题的更详细说明


Ros*_*ews 15

HttpRequest.META更具体地说HttpRequest.META.get('HTTP_ACCEPT')- 而不是HttpRequest.META.get('CONTENT_TYPE')如前所述

  • 我知道这是旧的,但虽然这是可接受的答案,但这是不正确的.正如下面Jan的评论中提到的,正确的方法是'Accept'标题,可以通过`HttpRequest.META.get('HTTP_ACCEPT')`访问. (4认同)
  • 您可以执行回退,以处理这两种情况(加上默认值):`request.META.get('HTTP_ACCEPT',request.META.get('CONTENT_TYPE','application/your_default'))` (2认同)

Ant*_*ard 5

正如其他答案中所说,此信息位于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))
Run Code Online (Sandbox Code Playgroud)

例如,如果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 接受头规范质量值规范