python - 在 Django 测试中匹配查询集
问题描述
我有一个 Django 应用程序,在我的测试中我运行这个代码:
def test_search_keywords_logic(self):
response = self.client.get(reverse('search-results'), { 'q': 'test11' })
nt.assert_equal(response.status_code, 200)
nt.assert_equal(response.context['query_string'], 'test11')
nt.assert_equal(response.context['total_results'], 1)
nt.assert_equal(response.context['found_results'], True)
qs = QuerySet(CaseStudy.objects.filter(title='test1'))
nt.assert_queryset_equal(response.context['study_results'], qs)
最后一行:nt.assert_queryset_equal(response.context['study_results'], qs)
给我错误:AttributeError: 'QuerySet' object has no attribute '_meta'
我不确定这意味着什么。我要做的就是断言上下文变量“study_results”中返回的查询集与我知道CaseStudy.objects.get(title='test1')
的应该返回正确的 CaseStudy 对象相匹配,因为它是测试数据库中唯一的一个。但是,它似乎不起作用。我还尝试将响应上下文 'study_results' 与 'study_results' 进行比较<CaseStudy: test1>
,甚至尝试将其包装在QuerySet()
. 它仍然不起作用,似乎将我QuerySet()
的 for test1 视为 test1 字符串分为单个字符的列表。
我试过两者都用nt.assert_equal()
,nt.assert_queryset_equal()
也不管用。
让这些断言通过的正确/有效方法是什么?我知道 study_results 上下文在这种情况下返回 CaseStudy: test1 。我似乎无法让它在断言中匹配。因为我从objects.filter
它已经是一个查询集得到它,但即使.get()
我无法让它工作。
我的问题似乎在比较的右侧,即使我只是输入'test1
or<CaseStudy: test1>
或QuerySet('test1')
它不起作用。
任何帮助,将不胜感激。
编辑:
使用此代码遇到此错误:
qs = CaseStudy.objects.filter(title='test1')
nt.assert_queryset_equal(response.context['study_results'], qs)
错误:
FAIL: test_search_keywords_logic (sasite.tests.tests.TestSearch)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/app/sasite/tests/tests.py", line 62, in test_search_keywords_logic
nt.assert_queryset_equal(response.context['study_results'], qs)
File "/usr/local/lib/python3.6/site-packages/django/test/testcases.py", line 972, in assertQuerysetEqual
return self.assertEqual(list(items), values, msg=msg)
AssertionError: Lists differ: ['test1'] != [test1]
First differing element 0:
'test1'
test1
- ['test1']
? - -
+ [test1]
编辑2:
相关搜索结果查看代码:
keywords_dicts_study = CaseStudy.objects.all().values('pk', 'keywords', 'category')
match_set_study = set()
target = []
for kd in keywords_dicts_study:
keywords = kd['keywords'].split(',')
for word in keywords:
target.append(word)
target.append(kd['category'])
for query in normalize_query(query_string):
for x in target:
if query.lower().strip(',').strip() == x.lower().strip():
match_set_study.add(kd['pk'])
编辑3:
我将代码更改为:
qs = CaseStudy.objects.filter(title='test1')
nt.assert_equal(response.context['study_results'], [qs])
现在得到这个错误:
Traceback (most recent call last):
File "/app/sasite/tests/tests.py", line 62, in test_search_keywords_logic
nt.assert_queryset_equal(response.context['study_results'], [qs])
File "/usr/local/lib/python3.6/site-packages/django/test/testcases.py", line 972, in assertQuerysetEqual
return self.assertEqual(list(items), values, msg=msg)
AssertionError: Lists differ: ['test1'] != [<QuerySet [test1]>]
First differing element 0:
'test1'
<QuerySet [test1]>
- ['test1']
+ [<QuerySet [test1]>]
所以它现在将 my[qs]
视为一个 QuerySet。但它似乎不是response.context['page_results']
QuerySet 本身。我不应该在这里使用nt.assert_queryset_equal()
吗?而只是使用nt.assert_equal()
?
究竟是什么response.context['page_results']
?它本身是一个 QuerySet 吗?因为好像不是这样。它作为['test1']
. 如果我更改[qs]
为,qs
那么我将获得'[test1]'
该值。我似乎无法让它们正确对齐。
我的目标是nt.assert_queryset_equal()
最终成为真正的使用response.contex['study_results']
和CaseStudy.objects.filter(title='test1')
有人可以建议一种方法来实现这一目标吗?
谢谢
解决方案
我不确定你为什么在那个查询上调用 QuerySet。filter()
已经返回一个查询集;似乎没有任何理由将其包装在另一个中。你应该删除它。
qs = CaseStudy.objects.filter(title='test1')
nt.assert_queryset_equal(response.context['study_results'], qs)
推荐阅读
- java - 如何显示带有注释且没有嵌入字体的 PDF?
- xslt - 使用 XSLT 按节点数将大型 XML 拆分为较小的块
- python-3.x - Jupyterlab 中的 Geopandas (read_file) CRSError 消息
- reactjs - 如何在 React.js 中自定义 Material-UI KeyboardDatePicker 的 ToolbarComponent?
- sql - 将正则表达式查询转换为 SQL Server
- javascript - 如何从 fb messenger chat 访问 [object Promise] 值
- php - php在while循环中选择一个随机数组值并将其分配给一个变量
- kotlin - 运行作业超过 10 秒时的协程回调
- javascript - 在 JavaScript 中将数字按 0.5 舍入到小数点后 1 位
- entity-framework - EF- INCLUDE 表中的两个 WHERE IN 子句在发送到服务器的 SQL 中产生两个 EXISTS