Django self.client.post 不发送数据给装饰器查看
Django self.client.post does not send data to view with decorator
我有一个简单的测试用例,它检查 POST
请求是否包含有效数据 returns 一个 HTML 响应是否包含 200 状态代码:
class PostRequestTestCase(TestCase):
def test_valid_post_request(self):
response = self.client.post('/foo/', data={'text': 'bar'})
self.assertEqual(response.status_code, 200)
这是为该请求触发的视图 foo
:
logger = logging.getLogger(__name__)
# decorator to trace enter and exit events
enter_exit_tracer = enter_exit_Tracer(logger)
@enter_exit_tracer
def foo(request):
if request.method == 'POST':
#
print('request.POST:', request.POST)
#
# some stuff
其中 @enter_exit_tracer
是跟踪 entering/exiting 函数的装饰器:
def enter_exit_Tracer(logger):
def middle(f):
def inner(*args, **kwargs):
session_string = args[-1] if 'session_key' in args[-1] else '[]'
logger.debug('%s Enter %s.', session_string, f.__name__)
result = f(*args, **kwargs)
logger.debug('%s Exit %s.', session_string, f.__name__)
return result
return inner
return middle
事实证明,当我将这个装饰器添加到foo
函数时,通过self.client.post
发送的POST
数据实际上并没有传递给foo
。它们在测试请求中丢失了 - 所以我的测试失败了:
DEBUG: [] Enter foo.
request.POST: <QueryDict: {}>
ERROR: Invalid form
F
======================================================================
FAIL: test_valid_post_request (textstat.tests.PostRequestTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/user/Pro/myapp/tests.py", line 111, in test_valid_post_request
self.assertEqual(response.status_code, 200)
AssertionError: 400 != 200
----------------------------------------------------------------------
Ran 1 test in 0.018s
FAILED (failures=1)
我们看到 request.POST: <QueryDict: {}>
并最终导致 ERROR: Invalid form
。
与此同时,当我执行类似的 POST
请求时,但通过网络浏览器一切正常 - 表单填充了数据,网页呈现正常,@enter_exit_tracer
执行其按预期记录。
如果我注释掉 @enter_exit_tracer
装饰器,那么一切正常,测试通过:
request.POST: <QueryDict: {'text': ['bar']}>
.
----------------------------------------------------------------------
Ran 1 test in 0.007s
OK
问题:
- 为什么在
self.client.post
请求的情况下 request.POST
数据没有通过装饰器传递到视图?
- 如果装饰器有任何问题 - 为什么 Web 请求工作正常?
- 是否可以保留装饰器并
self.client.post
将数据传递给视图?
原来装饰器在这一行出现了TypeError
错误:
session_string = args[-1] if 'session_key' in args[-1] else '[]'
所以当 args[-1]
不是 str
时,这应该不起作用。用 str(args[-1])
修复它解决了缺少 POST
数据的整个问题。
奇怪的是 self.client.post
没有引发任何 TypeError
并且 session_string
是以某种方式计算出来的。而不是这个 POST
数据没有发送到视图,没有任何错误或提示警告。 POST
数据刚刚消失。同时,当从 Web 浏览器发送 POST
请求时,相同的代码工作正常,因此错误没有被注意到。
我有一个简单的测试用例,它检查 POST
请求是否包含有效数据 returns 一个 HTML 响应是否包含 200 状态代码:
class PostRequestTestCase(TestCase):
def test_valid_post_request(self):
response = self.client.post('/foo/', data={'text': 'bar'})
self.assertEqual(response.status_code, 200)
这是为该请求触发的视图 foo
:
logger = logging.getLogger(__name__)
# decorator to trace enter and exit events
enter_exit_tracer = enter_exit_Tracer(logger)
@enter_exit_tracer
def foo(request):
if request.method == 'POST':
#
print('request.POST:', request.POST)
#
# some stuff
其中 @enter_exit_tracer
是跟踪 entering/exiting 函数的装饰器:
def enter_exit_Tracer(logger):
def middle(f):
def inner(*args, **kwargs):
session_string = args[-1] if 'session_key' in args[-1] else '[]'
logger.debug('%s Enter %s.', session_string, f.__name__)
result = f(*args, **kwargs)
logger.debug('%s Exit %s.', session_string, f.__name__)
return result
return inner
return middle
事实证明,当我将这个装饰器添加到foo
函数时,通过self.client.post
发送的POST
数据实际上并没有传递给foo
。它们在测试请求中丢失了 - 所以我的测试失败了:
DEBUG: [] Enter foo.
request.POST: <QueryDict: {}>
ERROR: Invalid form
F
======================================================================
FAIL: test_valid_post_request (textstat.tests.PostRequestTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/user/Pro/myapp/tests.py", line 111, in test_valid_post_request
self.assertEqual(response.status_code, 200)
AssertionError: 400 != 200
----------------------------------------------------------------------
Ran 1 test in 0.018s
FAILED (failures=1)
我们看到 request.POST: <QueryDict: {}>
并最终导致 ERROR: Invalid form
。
与此同时,当我执行类似的 POST
请求时,但通过网络浏览器一切正常 - 表单填充了数据,网页呈现正常,@enter_exit_tracer
执行其按预期记录。
如果我注释掉 @enter_exit_tracer
装饰器,那么一切正常,测试通过:
request.POST: <QueryDict: {'text': ['bar']}>
.
----------------------------------------------------------------------
Ran 1 test in 0.007s
OK
问题:
- 为什么在
self.client.post
请求的情况下request.POST
数据没有通过装饰器传递到视图? - 如果装饰器有任何问题 - 为什么 Web 请求工作正常?
- 是否可以保留装饰器并
self.client.post
将数据传递给视图?
原来装饰器在这一行出现了TypeError
错误:
session_string = args[-1] if 'session_key' in args[-1] else '[]'
所以当 args[-1]
不是 str
时,这应该不起作用。用 str(args[-1])
修复它解决了缺少 POST
数据的整个问题。
奇怪的是 self.client.post
没有引发任何 TypeError
并且 session_string
是以某种方式计算出来的。而不是这个 POST
数据没有发送到视图,没有任何错误或提示警告。 POST
数据刚刚消失。同时,当从 Web 浏览器发送 POST
请求时,相同的代码工作正常,因此错误没有被注意到。