python - Django 休息框架 : custom headers are different in client than unittests

标签 python django rest django-rest-framework

我有一个 Django Rest API,然后单独有一个使用此 API 的客户端。

我在客户端中使用请求传递自定义 header :

r = requests.get(url, params=params, headers={'license': '12345'})

然后在 API 中,在我的自定义权限中,我得到如下标题:

app_license = request.META['HTTP_LICENSE']

我知道 django rewrites the custom headers出于安全原因,所以它工作正常。

我的问题是当我在 Django rest API 中编写单元测试时:

response = self.client.get(self.url, params=params, headers={'license': '12345'})

然后它升起:

KeyError: 'HTTP_LICENSE'

但是如果我像这样更改代码,测试会毫无问题地通过,但消费者不工作:

request.META['headers']['license']

我可以检查是否有 'headers' 键,但我不想更改代码只是为了通过单元测试,它一定是某种方式来编写符合实际的单元测试,对吧?

我尝试使用:

from django.test import TestCase

和:

from rest_framework.test import APITestCase

两者的结果相同。有什么解决办法吗?谢谢!

最佳答案

TL;DR — 如果您想在 META 中显示某些内容,请将其设为 kwargclient.get 方法是与 requests.get 不同的签名。


这是因为 self.client.get 的 kwargs 直接映射到 HTTP 属性。

拍一个look at the source .您会注意到堆栈是:

  1. 获取
  2. 通用
  3. 请求
  4. _base_environ

在该过程中,kwargs 被传送到 _base_environ,几乎没有改动。然后将它们合并到一个字典中,其中包含您期望的所有基本标题:

    # This is a minimal valid WSGI environ dictionary, plus:
    # - HTTP_COOKIE: for cookie support,
    # - REMOTE_ADDR: often useful, see #8551.
    # See http://www.python.org/dev/peps/pep-3333/#environ-variables
    environ = {
        'HTTP_COOKIE': self.cookies.output(header='', sep='; '),
        'PATH_INFO': '/',
        'REMOTE_ADDR': '127.0.0.1',
        'REQUEST_METHOD': 'GET',
        'SCRIPT_NAME': '',
        'SERVER_NAME': 'testserver',
        'SERVER_PORT': '80',
        'SERVER_PROTOCOL': 'HTTP/1.1',
        'wsgi.version': (1, 0),
        'wsgi.url_scheme': 'http',
        'wsgi.input': FakePayload(b''),
        'wsgi.errors': self.errors,
        'wsgi.multiprocess': True,
        'wsgi.multithread': False,
        'wsgi.run_once': False,
    }
    environ.update(self.defaults)
    environ.update(request)
    return environ

然后将上述内容传递到 request 方法中的 WSGIRequest 对象。 That class then takes the provided environ dict and assigns it to the META property:

class WSGIRequest(HttpRequest):
    def __init__(self, environ):
        script_name = get_script_name(environ)
        # If PATH_INFO is empty (e.g. accessing the SCRIPT_NAME URL without a
        # trailing slash), operate as if '/' was requested.
        path_info = get_path_info(environ) or '/'

        ##############################
        ##                          ##
        ## This is the line you're  ##
        ##       looking for.       ##
        ##                          ##
        ##############################
        self.environ = environ
        self.path_info = path_info

关于python - Django 休息框架 : custom headers are different in client than unittests,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49909224/

相关文章:

python - tensorflow : . eval() 永远不会结束

python - Pandas 变换: creating two columns with function

python - 更改spark中的时间戳TZ

python - django-admin.py startproject mysite 没有执行任何操作

java - Jersey client.setChunkedEncodingSize(null) 不起作用

javascript - 如何在 AngularJS 中处理来自 REST Api 的日期字段?

python - 如何访问 gensim word2vec 中的输出嵌入(输出向量)?

django 如何将 get_or_create 与 FileField 和 upload_to 一起使用

django - crispy-form 的 Helper 没有生效

api - NestJS REST Controller 未从 PATCH 请求中获取 @Body(VSCode REST 客户端)