【问题标题】:Django test fails with "No User matches the given query."Django 测试失败并显示“没有用户匹配给定的查询”。
【发布时间】:2021-11-21 15:00:14
【问题描述】:

我编写了 Django 应用程序,现在我试图用自动化测试来覆盖它。为了在我的ListView 中测试get_queryset 函数,我创建了一个测试用户和他的帖子,但我的测试失败并显示"No User matches the given query"。当我执行py manage.py runserver 时,一切都很好,没有引发异常并且页面显示正确。我是 Django 测试的新手,所以我完全不知道发生了什么。你能帮帮我吗?

这是我在 view.py 中的观点

class UserPostListView(ListView):
"""Displaying a page with a certain user's posts"""
model = Post
template_name = 'blog/user_posts.html'
context_object_name = 'posts'
paginate_by = 5

def get_queryset(self):
    """Dynamic filtering to get posts by a chosen user"""
    queryset = super().get_queryset()
    user = get_object_or_404(User, username=self.kwargs.get('username'))
    return queryset.filter(author=user).order_by('-date_posted')

测试该视图:

class TestUserPostListView(TestCase):
"""Test UserPostListView"""

def setUp(self):
    """Creating a test user and his post to see if the certain
    user's page with posts is displayed properly"""

    self.factory = RequestFactory()
    
    self.user = User.objects.create_user(
        username='test_user',
        email='testuser@example.com',
        password='fhhewo87539275'
    )
    self.post = Post.objects.create(
        title='test_post',
        content='blabla',
        author=self.user
    )
    
def test_get_queryset(self):
    """Testing get_queryset function"""
    url = reverse('user-posts', kwargs={'username': self.user.username})
    request = self.factory.get(url)
    view = UserPostListView()
    view.setup(request)

    queryset = view.get_queryset()
    self.assertIn(self.post, queryset)

追溯:

Traceback (most recent call last):
File "C:\Users\473491\Documents\django\web_blog\env\lib\site-packages\django\shortcuts.py", line 76, in get_object_or_404
return queryset.get(*args, **kwargs)
File "C:\Users\473491\Documents\django\web_blog\env\lib\site-packages\django\db\models\query.py", line 435, in get
raise self.model.DoesNotExist(django.contrib.auth.models.User.DoesNotExist: User matching query does not exist.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "C:\Users\473491\Documents\django\web_blog\web_blog\apps\blog\test\test_views.py", line 67, in test_get_queryset
queryset = view.get_queryset()
File "C:\Users\473491\Documents\django\web_blog\web_blog\apps\blog\views.py", line 45, in get_queryset
user = get_object_or_404(User, username=self.kwargs.get('username'))
File "C:\Users\473491\Documents\django\web_blog\env\lib\site-packages\django\shortcuts.py", line 78, in get_object_or_404
raise Http404('No %s matches the given query.' % queryset.model._meta.object_name)

django.http.response.Http404:没有用户匹配给定的查询。

【问题讨论】:

  • self.kwargs.get('username') 是否返回无?在视图中打印 User.objects.all() 会发生什么?
  • 它没有。当我打印 User.objects.all() 我得到 , , ]> 因为我创建了一些用户来手动测试我的应用程序。在运行测试时创建空的 DB 实例。
  • 这可能有点没用,但可以尝试像示例中那样 docs.djangoproject.com/en/3.2/topics/testing/advanced/#example UserPostListView.as_view()(request)
  • 我已经阅读了文档并按照它编写了我的测试。我意识到queryset = view.get_queryset() 有问题,但我不明白发生了什么
  • 也许从打印 self.kwargs.get('username') 开始,看看它是否返回您期望的实际用户

标签: python django django-testing


【解决方案1】:

我发现问题出在哪里。我的UserPostListView 被包含 url-variable 的 url 调用。

我的视图对应的urlpattern:

path('users/<str:username>', UserPostListView.as_view(), name='user-posts')

我还使用 url 中的 username 通过调用 UserPostListView 中的 get_queryset 函数来过滤使用该用户名的用户创建的帖子。

我仔细阅读了文档,发现:

在请求/响应周期中调用视图时,setup() 方法将 HttpRequest 分配给视图的请求属性,并将从 URL 模式捕获的任何位置和/或关键字参数分别分配给 args 和 kwargs 属性.

这意味着我必须写view.setup(request, username=self.user.username)而不是view.setup(request)

当我修复它时,测试开始正常运行并且没有失败。

【讨论】:

    猜你喜欢
    • 2021-05-07
    • 1970-01-01
    • 2015-10-10
    • 2017-03-08
    • 1970-01-01
    • 1970-01-01
    • 2019-01-30
    • 2020-10-04
    • 2019-07-21
    相关资源
    最近更新 更多