我在Django应用程序中有以下视图:
class VideoCreateView(View):
"""
Handle creating a video
"""
template_name = 'albums/video_create.html'
success_template_name = 'albums/video_created.html'
def get(self, request, *args, **kwargs):
"""
Display the confirmation dialogue
"""
# First, get the album
pk = kwargs['pk']
try:
album = Album.objects.get(id=pk)
except Album.DoesNotExist:
raise Http404
# Render the template
return render(request, self.template_name)
def post(self, request, *args, **kwargs):
"""
Generate the video
"""
# First, get the album
pk = kwargs['pk']
try:
album = Album.objects.get(id=pk)
except Album.DoesNotExist:
raise Http404
# Trigger build
if len(album.photo_set.all()) > 0:
celery_generate_video.delay(album)
# Send response
return render(request, self.success_template_name)
else:
raise HttpResponseBadRequest
这需要URL中相册的ID,如果相册不存在,则应该引发404错误。我已编写以下测试来检查此行为:
@mock.patch('storages.backends.s3boto.S3BotoStorage', FileSystemStorage)
def test_get_does_not_exist(self):
"""
Test GET requests
"""
pk = uuid.uuid4()
url = reverse('video_create', kwargs={
'pk': pk.urn[9:]
})
request = self.factory.get(url)
request.user = self.user
response = VideoCreateView.as_view()(request, pk=pk)
self.assertEqual(response.status_code, 404)
不幸的是,它引发了以下错误:
======================================================================
ERROR: test_get_does_not_exist (albums.tests.VideoCreateViewTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/matthew/Projects/digitallife/albums/views.py", line 200, in get
album = Album.objects.get(id=pk)
File "/home/matthew/Projects/digitallife/venv/lib/python3.4/site-packages/django/db/models/manager.py", line 127, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/matthew/Projects/digitallife/venv/lib/python3.4/site-packages/django/db/models/query.py", line 334, in get
self.model._meta.object_name
albums.models.DoesNotExist: Album matching query does not exist.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib/python3.4/unittest/mock.py", line 1125, in patched
return func(*args, **keywargs)
File "/home/matthew/Projects/digitallife/albums/tests.py", line 573, in test_get_does_not_exist
response = VideoCreateView.as_view()(request, pk=pk)
File "/home/matthew/Projects/digitallife/venv/lib/python3.4/site-packages/django/views/generic/base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "/home/matthew/Projects/digitallife/venv/lib/python3.4/site-packages/django/views/generic/base.py", line 89, in dispatch
return handler(request, *args, **kwargs)
File "/home/matthew/Projects/digitallife/albums/views.py", line 202, in get
raise Http404
django.http.response.Http404
在我看来,这个例外并没有被抓住。我之前使用过这种方法来捕获Django中的无效对象,但那是在Python 2.7中,所以我想知道它是否是Python 3中的东西(这是我的第一个Python 3 Django项目)。我做错了什么?
答案 0 :(得分:4)
你在视图中没有做错任何事。测试结果显示它正在完全按照您的要求执行:捕获DoesNotExist,并在响应中提升Http404。
问题出在你的考试中。您直接调用该视图,这意味着您跳过所有通常执行处理异常并将其转换为404/500响应的中间件。您应该使用内置测试客户端来调用视图,而不是通过工厂创建请求:
url = ...
response = self.client.get(url)