Python Django-运行测试时,必须使用对象pk或slug调用通用详细视图
我已经搜索了关于同一错误消息的其他问题,但它似乎对我有用(我使用的是Django 2 btw) 我的路径:Python Django-运行测试时,必须使用对象pk或slug调用通用详细视图,python,django,Python,Django,我已经搜索了关于同一错误消息的其他问题,但它似乎对我有用(我使用的是Django 2 btw) 我的路径: path('<slug:slug>', views.BookDetailView.as_view(), name='book-detail'), 尽管如此,它在运行测试时仍会抛出错误消息(通常通过浏览器请求视图时会起作用) 以下是适当的测试功能(使用RequestFactory和mixer) 以下是回溯: _______________________ TestBookDet
path('<slug:slug>', views.BookDetailView.as_view(), name='book-detail'),
尽管如此,它在运行测试时仍会抛出错误消息(通常通过浏览器请求视图时会起作用)
以下是适当的测试功能(使用RequestFactory和mixer)
以下是回溯:
_______________________ TestBookDetailView.test_access ________________________
self = <books.tests.test_books_views.TestBookDetailView object at 0x000001C8E3577240>
def test_access(self):
mixer.blend('books.Book', name='The Book')
req = RequestFactory().get('/books/the_book')
req.user = mixer.blend(User)
> resp = BookDetailView.as_view()(req)
books\tests\test_books_views.py:29:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
..\..\envs\booknote\lib\site-packages\django\views\generic\base.py:69: in view
return self.dispatch(request, *args, **kwargs)
..\..\envs\booknote\lib\site-packages\django\utils\decorators.py:62: in _wrapper
return bound_func(*args, **kwargs)
..\..\envs\booknote\lib\site-packages\django\contrib\auth\decorators.py:21: in _wrapped_view
return view_func(request, *args, **kwargs)
..\..\envs\booknote\lib\site-packages\django\utils\decorators.py:58: in bound_func
return func.__get__(self, type(self))(*args2, **kwargs2)
..\..\envs\booknote\lib\site-packages\django\views\generic\base.py:89: in dispatch
return handler(request, *args, **kwargs)
..\..\envs\booknote\lib\site-packages\django\views\generic\detail.py:105: in get
self.object = self.get_object()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <books.views.BookDetailView object at 0x000001C8E357CD68>
queryset = <QuerySet [<Book: Book object (1)>]>
def get_object(self, queryset=None):
"""
Return the object the view is displaying.
Require `self.queryset` and a `pk` or `slug` argument in the URLconf.
Subclasses can override this to return any object.
"""
# Use a custom queryset if provided; this is required for subclasses
# like DateDetailView
if queryset is None:
queryset = self.get_queryset()
# Next, try looking up by primary key.
pk = self.kwargs.get(self.pk_url_kwarg)
slug = self.kwargs.get(self.slug_url_kwarg)
if pk is not None:
queryset = queryset.filter(pk=pk)
# Next, try looking up by slug.
if slug is not None and (pk is None or self.query_pk_and_slug):
slug_field = self.get_slug_field()
queryset = queryset.filter(**{slug_field: slug})
# If none of those are defined, it's an error.
if pk is None and slug is None:
raise AttributeError("Generic detail view %s must be called with "
"either an object pk or a slug."
> % self.__class__.__name__)
E AttributeError: Generic detail view BookDetailView must be called with either an object pk or a slug.
..\..\envs\booknote\lib\site-packages\django\views\generic\detail.py:47: AttributeError
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu________________________
自我=
def测试_访问(自):
mixer.blend('books.Book',name='The Book')
req=RequestFactory().get('/books/the_book')
req.user=混合器混合(用户)
>resp=BookDetailView.as_view()(req)
books\tests\test\u books\u views.py:29:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
..\..\envs\booknote\lib\site packages\django\views\generic\base.py:69:视图中
返回自调度(请求,*args,**kwargs)
..\..\envs\booknote\lib\site packages\django\utils\decorators.py:62:in\u包装
返回边界函数(*args,**kwargs)
..\..\envs\booknote\lib\site packages\django\contrib\auth\decorators.py:21:在包装视图中
返回视图功能(请求,*args,**kwargs)
..\..\envs\booknote\lib\site packages\django\utils\decorators.py:58:in-bound\u func
返回函数获取(self,键入(self))(*args2,**kwargs2)
..\..\envs\booknote\lib\site packages\django\views\generic\base.py:89:处于分派中
返回处理程序(请求、*args、**kwargs)
..\..\envs\booknote\lib\site packages\django\views\generic\detail.py:105:in get
self.object=self.get_object()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
自我=
查询集=
def get_对象(self,queryset=None):
"""
返回视图显示的对象。
在URLconf中需要'self.queryset'和'pk'或'slug'参数。
子类可以重写此项以返回任何对象。
"""
#使用自定义查询集(如果提供);这是子类所必需的
#比如DateDetailView
如果queryset为无:
queryset=self.get_queryset()
#接下来,尝试按主键查找。
pk=self.kwargs.get(self.pk\u url\u kwarg)
slug=self.kwargs.get(self.slug\u url\u kwarg)
如果pk不是None:
queryset=queryset.filter(pk=pk)
#下一步,试着用slug向上看。
如果slug不是None和(pk是None或self.query\u pk\u和\u slug):
slug\u field=self.get\u slug\u field()
queryset=queryset.filter(**{slug\u字段:slug})
#如果这些都没有定义,那就是一个错误。
如果pk为无,slug为无:
raise AttributeError(“必须使用调用通用详细信息视图%s)”
“对象pk或slug。”
>%self.\uuuuuu类\uuuuuuu名\uuuuuuu)
E AttributeError:必须使用对象主键或slug调用常规详细视图BookDetailView。
..\..\envs\booknote\lib\site packages\django\views\generic\detail.py:47:AttributeError
我做错了什么
提前感谢您需要在测试中明确地通过URL参数
resp = BookDetailView.as_view()(req, slug="the_book"))
或者使用内置测试客户机,而不是到处乱搞请求工厂:
self.client.force_login(user)
resp = self.client.get("/books/the_book")
您不需要
slug\u url\u kwarg
属性,因为“slug”是默认值。但这两种方法都应该奏效;你能发布完整的回溯吗?对不起,这个问题实际上只在运行我的测试时出现(因此,我猜测试函数中有错误)。通过浏览器访问时,它工作正常。我更新了问题,包括测试和回溯。
_______________________ TestBookDetailView.test_access ________________________
self = <books.tests.test_books_views.TestBookDetailView object at 0x000001C8E3577240>
def test_access(self):
mixer.blend('books.Book', name='The Book')
req = RequestFactory().get('/books/the_book')
req.user = mixer.blend(User)
> resp = BookDetailView.as_view()(req)
books\tests\test_books_views.py:29:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
..\..\envs\booknote\lib\site-packages\django\views\generic\base.py:69: in view
return self.dispatch(request, *args, **kwargs)
..\..\envs\booknote\lib\site-packages\django\utils\decorators.py:62: in _wrapper
return bound_func(*args, **kwargs)
..\..\envs\booknote\lib\site-packages\django\contrib\auth\decorators.py:21: in _wrapped_view
return view_func(request, *args, **kwargs)
..\..\envs\booknote\lib\site-packages\django\utils\decorators.py:58: in bound_func
return func.__get__(self, type(self))(*args2, **kwargs2)
..\..\envs\booknote\lib\site-packages\django\views\generic\base.py:89: in dispatch
return handler(request, *args, **kwargs)
..\..\envs\booknote\lib\site-packages\django\views\generic\detail.py:105: in get
self.object = self.get_object()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <books.views.BookDetailView object at 0x000001C8E357CD68>
queryset = <QuerySet [<Book: Book object (1)>]>
def get_object(self, queryset=None):
"""
Return the object the view is displaying.
Require `self.queryset` and a `pk` or `slug` argument in the URLconf.
Subclasses can override this to return any object.
"""
# Use a custom queryset if provided; this is required for subclasses
# like DateDetailView
if queryset is None:
queryset = self.get_queryset()
# Next, try looking up by primary key.
pk = self.kwargs.get(self.pk_url_kwarg)
slug = self.kwargs.get(self.slug_url_kwarg)
if pk is not None:
queryset = queryset.filter(pk=pk)
# Next, try looking up by slug.
if slug is not None and (pk is None or self.query_pk_and_slug):
slug_field = self.get_slug_field()
queryset = queryset.filter(**{slug_field: slug})
# If none of those are defined, it's an error.
if pk is None and slug is None:
raise AttributeError("Generic detail view %s must be called with "
"either an object pk or a slug."
> % self.__class__.__name__)
E AttributeError: Generic detail view BookDetailView must be called with either an object pk or a slug.
..\..\envs\booknote\lib\site-packages\django\views\generic\detail.py:47: AttributeError
resp = BookDetailView.as_view()(req, slug="the_book"))
self.client.force_login(user)
resp = self.client.get("/books/the_book")