我这里有一个 View ,它向数据库添加一个新的 List
并重定向到 List
页面。我在模型类中配置了 get_absolute_url
。它似乎工作得很好。
def new_list(request):
form = ItemForm(request.POST)
if form.is_valid():
list_ = List()
list_.owner = request.user
list_.save()
form.save(for_list=list_)
return redirect(list_)
else:
return render(request, 'home.html', {'form': form})
但是当我尝试使用 unitest.mock
中的 patch
模拟模型类和表单类时,问题发生了
class TestMyLists(TestCase):
@patch('lists.views.List')
@patch('lists.views.ItemForm')
def test_list_owner_is_saved_if_user_is_authenticated(
self, mockItemFormClass, mockListClass
):
user = User.objects.create(email='a@b.com')
self.client.force_login(user)
self.client.post('/lists/new', data={'text': 'new item'})
mock_list = mockListClass.return_value
self.assertEqual(mock_list.owner, user)
当我运行测试时,出现如下错误:
Traceback (most recent call last):
File "/home/sjsakib/.virtualenvs/superlists/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
response = get_response(request)
File "/home/sjsakib/.virtualenvs/superlists/lib/python3.6/site-packages/django/core/handlers/base.py", line 128, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/sjsakib/.virtualenvs/superlists/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/mnt/BAC4BB93C4BB4FFD/codes/tdd/superlists/lists/views.py", line 36, in new_list
return redirect(list_)
File "/home/sjsakib/.virtualenvs/superlists/lib/python3.6/site-packages/django/shortcuts.py", line 58, in redirect
return redirect_class(resolve_url(to, *args, **kwargs))
File "/home/sjsakib/.virtualenvs/superlists/lib/python3.6/site-packages/django/http/response.py", line 407, in __init__
self['Location'] = iri_to_uri(redirect_to)
File "/home/sjsakib/.virtualenvs/superlists/lib/python3.6/site-packages/django/utils/encoding.py", line 151, in iri_to_uri
return quote(iri, safe="/#%[]=:;$&()+,!?*@'~")
File "/usr/local/lib/python3.6/urllib/parse.py", line 787, in quote
return quote_from_bytes(string, safe)
File "/usr/local/lib/python3.6/urllib/parse.py", line 812, in quote_from_bytes
raise TypeError("quote_from_bytes() expected bytes")
TypeError: quote_from_bytes() expected bytes
重定向功能似乎不适用于模拟对象。我怎样才能解决这个问题? 我正在使用 Django 2.0.1
最佳答案
我正在学习相同的教程,但我遇到了相同的错误,但我在这里找到了解决方案:Mock() function gives TypeError in django2
原因是:
Django 2 在某些地方不再支持字节串,因此当 View 重定向模拟类列表时,它作为模拟对象执行并且 iri_to_uri django 函数抛出错误。
在 django 1.11 中,iri_to_uri 强制 iri 返回一个字节 return quote(force_bytes(iri), safe="/#%[]=:;$&()+,!?@'~") 而不是现在是 return quote(iri, safe="/#%[]=:;$&()+,!?@'~")。
所以解决方案是在 lists.views.py 中返回 redirect(str(list_.get_absolute_url())) 而不是 return redirect(list_)
这是我的例子:
def new_list(request):
form = ItemForm(data=request.POST)
if form.is_valid():
list_ = List()
list_.owner = request.user
list_.save()
form.save(for_list=list_)
return redirect(str(list_.get_absolute_url()))
else:
return render(request, 'home.html', {"form": form})
关于python - 模拟 Django 模型类时无法重定向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48720028/