如何访问 Django Rest Framework 上的自定义 HTTP 请求标头?

Posted

技术标签:

【中文标题】如何访问 Django Rest Framework 上的自定义 HTTP 请求标头?【英文标题】:How to access custom HTTP request headers on Django Rest Framework? 【发布时间】:2015-02-05 13:58:19 【问题描述】:

我正在向使用 django rest 框架创建的 API 发送一个发布请求:

curl --header "X-MyHeader: 123" --data "test=test" http://127.0.0.1:8000/api/update_log/

在我的rest框架视图中,我想获取我的costum header,如果自定义header满足条件,我会继续分析我的post数据。

好的,我的视图如下:

class PostUpdateLogView(APIView):
    throttle_classes = ()
    permission_classes = ()
    parser_classes = (
        parsers.FormParser,
        parsers.MultiPartParser,
        parsers.JSONParser,
    )  

    renderer_classes = (renderers.JSONRenderer,)

    def post(self, request):
        print request.Meta
        # Get custom header
        # Validate custom header
        # Proceed to analize post data

        # Make response
        content = 
            'response': 'response',
        

        return Response(content)

我试图在 request.Meta 元素上找到我的自定义标头,但是当我打印 request.Meta 时,我收到 500 错误。如果我打印 request.data,我会得到预期的响应。

¿使用 django rest 框架在我的 post 请求中获取自定义标头的方法是什么?

【问题讨论】:

【参考方案1】:

请求的元数据属性名大写:

print request.META

如果您的标头名为“My-Header”,您的标头将显示为:

request.META['HTTP_MY_HEADER']

或者:

request.META.get('HTTP_MY_HEADER') # return `None` if no such header

Quote from the documentation:

通过将所有字符转换为大写、用下划线替换任何连字符并在名称中添加HTTP_ 前缀,将请求中的 HTTP 标头转换为 META 键。因此,例如,名为 X-Bender 的标头将映射到 METAHTTP_X_BENDER

【讨论】:

很抱歉,就像丢失了 (;),我花了两个小时在这...也许,您知道当我使用 curl 请求 api 时如何查看错误详细信息吗?当我使用 curl 发送发布请求时,我只能在控制台上看到类似 [05/Feb/2015 08:40:39] "POST /api/update_log/ HTTP/1.1" 500 78112 的答案,但我不能查看错误详细信息。谢谢你,原谅我的粗心。 curl 的输出重定向到该文件,然后在浏览器中打开该文件。 curl ... http://127.0.0.1:8000/api/update_log/ > error.html【参考方案2】:

如果您提供有效的标头信息并从后端获取该信息,请遵循这些信息

client-name='ABCKD'

那么您已经在 post 中获取了该客户信息或在此之后获取函数-

request.META['HTTP_CLIENT_NAME']

它会给你输出'ABCKD'。

请记住,无论您在请求的标头信息中提供的有效变量名称如何,django 都将其转换为大写并以“HTTP_”为前缀 在这里,它将客户端名称转换为CLIENT_NAME 并以HTTP_ 为前缀。 所以最终输出是 HTTP_CLIENT_NAME

【讨论】:

【参考方案3】:

看到这是一篇旧文章,我想我会分享自 Django 2.2 以来可用的更新、更灵活的方法。你可以使用request's headers object:

# curl --header "X-MyHeader: 123" --data "test=test" http://127.0.0.1:8000/api/update_log/

request.headers['X-MYHEADER']       # returns "123"
request.headers['x-myheader']       # case-insensitive, returns the same
request.headers.get('x-myheader')   # returns None if header doesn't exist

# standard headers are also available here
request.headers.get('Content-Type') # returns "application/x-www-form-urlencoded"

request.META 的最大区别在于request.headers 不会在标题前加上HTTP_,它不会将标题名称转换为UPPER_SNAKE_CASE,并且可以不区分大小写地访问标题。它只会在显示时将标题转换为Title-Casing(例如X-Myheader)。

【讨论】:

以上是关于如何访问 Django Rest Framework 上的自定义 HTTP 请求标头?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Django Rest Framework 将 url 字段添加到序列化程序

为啥 django-rest-framework 不显示 OneToOneField 数据 - django

django.test.client 上的 Django rest 框架导入错误

Django 和 Django 休息框架

无法使用 Django Rest 框架发送压缩的 gzip 数据

尽管有 AllowAny 权限,django-rest-framework 在 POST、PUT、DELETE 上返回 403 响应