请求对象中的Django REST Framework自定义标头

时间:2017-12-27 21:55:20

标签: python django django-rest-framework

当我通过@api_view装饰器创建新的API视图时,我在查看请求中的传入自定义标头时遇到问题。

我的自定义API视图如下所示:

 @api_view(['GET'])
 def TestView(request):
   print(request.META)
   return Response({'message': 'test'})

我期待的是做

之类的事情

curl --request GET \ --url http://localhost:8000/test \ --header 'custom: test'

我看到我的自定义标题custom出现在输出中。相反,它根本不存在。从文档中,它为request.META字段说明了以下内容:

A dictionary containing all available HTTP headers. Available headers depend on the client and server, but here are some examples:

然而,他们的输出中根本不会出现。我在这里错过了什么吗?

如果相关,我会注册我的网址:

urlpatterns = [url(r'test', views.TestView, name='test'), ...]

我的最终目标是编写一个自定义权限类,它将解析自定义标头并执行与身份验证相关的操作,并允许或拒绝请求。我的POC就是为了展示我所处理的基本例子。我可以提供print(request.META)的输出,但它只是一个文本墙而没有我预期的标题。

1 个答案:

答案 0 :(得分:2)

Django将HTTP_添加到自定义标头中。我认为(但不确定)它可能与here描述的某些安全问题有关。它还会将它们大写,因此custom标题变为HTTP_CUSTOM

from rest_framework.decorators import api_view
from rest_framework.response import Response

import logging

logger = logging.getLogger('django.test')

@api_view(['GET'])
def TestView(request):
    logger.info('Meta: %s' % request.META['HTTP_CUSTOM'])
    return Response({'message': 'test'})

正确输出(如果已按照here所述正确配置了记录):

Django version 2.0, using settings 'django_server.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
"GET /test HTTP/1.1" 301 0
Meta: test
"GET /test/ HTTP/1.1" 200 18

另外,正如您在上面的输出中所看到的,当API被命中时,Django会给出301重定向(我相信这是出于身份验证的目的吗?也不确定)所以你必须告诉你的cURL遵循重定向使用--location

curl --location --request GET \
     --header 'custom: test' http://localhost:8000/test

另请注意,标题名称中的所有连字符(-)都会转换为下划线符号(_),因此如果您将标题称为my-custom,则Django会对其进行转换到HTTP_MY_CUSTOM