【问题标题】:Determine the requested content type?确定请求的内容类型?
【发布时间】:2011-11-19 13:36:41
【问题描述】:

我想编写一个 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 上是否有此属性?

【问题讨论】:

    标签: django django-views


    【解决方案1】:

    HttpRequest.META,更具体地说是HttpRequest.META.get('HTTP_ACCEPT')——而不是前面提到的HttpRequest.META.get('CONTENT_TYPE')

    【讨论】:

    • 我知道这是旧的,但虽然这是公认的答案,但它是不正确的。正如下面 Jan 的评论中提到的,正确的方法是“Accept”标头,可通过 HttpRequest.META.get('HTTP_ACCEPT') 访问。
    • 你可以做一个后备来处理这两种情况(加上一个默认值):request.META.get('HTTP_ACCEPT', request.META.get('CONTENT_TYPE', 'application/your_default'))
    • 不知道是不是有什么变化,但我似乎不得不写:request.META.get('headers').get("HTTP_ACCEPT")
    • 自 2020 年起您可以使用 HttpRequest.content_type
    【解决方案2】:

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

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

    See more detailed description of these headers

    【讨论】:

      【解决方案3】:

      正如在其他答案中所说,此信息位于 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 specificationQuality Values specification

      【讨论】:

      • 这个答案应该替换顶部和接受的答案。
      【解决方案4】:

      在 django 1.10 中,您现在可以使用 request.content_type,如 their doc 中所述

      【讨论】:

      • 这将返回 'Content-Type' 而不是 'Accept' 标头。
      猜你喜欢
      • 2015-07-14
      • 1970-01-01
      • 2013-02-20
      • 2016-04-08
      • 1970-01-01
      • 1970-01-01
      • 2012-04-07
      • 2019-08-01
      • 1970-01-01
      相关资源
      最近更新 更多