比较django TestCase中的查询集

Amy*_*yth 18 django compare django-queryset testcase

我有一个非常简单的观点如下

def simple_view(request):
    documents = request.user.document_set.all()
    return render(request, 'simple.html', {'documents': documents})
Run Code Online (Sandbox Code Playgroud)

为了在我的测试用例中测试上面的视图,我有以下方法出错.

Class SomeTestCase(TestCase):
    # ...
    def test_simple_view(self):
        # ... some other checks
        docset = self.resonse.context['documents']
        self.assertTrue(self.user.document_set.all() == docset) # This line raises an error
    # ...
Run Code Online (Sandbox Code Playgroud)

我得到的错误是AssertionError: False is not true.我尝试打印两个查询集,两者完全相同.False当两个对象相同时,为什么会返回?有任何想法吗 ?

目前为了克服这一点,我使用了一个讨厌长度的讨厌的黑客如下:

ds1, ds2 = self.response.context['documents'], self.user.document_set.all()
self.assertTrue(len([x for x in ds1 if x in ds2]) == len(ds1) == len(ds2)) # Makes sure each entry in ds1 exists in ds2
Run Code Online (Sandbox Code Playgroud)

Mat*_*ohn 26

如果查询集对象是不同查询的结果,则它们将不相同,即使它们在结果中具有相同的值(比较ds1.queryds2.query).

如果首先将查询集转换为列表,则应该能够进行正常比较(假设它们具有相同的排序顺序):

self.assertEqual(list(ds1), list(ds2))
Run Code Online (Sandbox Code Playgroud)

  • 确实,可以将它们放在一个集合中,但这也可能隐藏一个查询集具有重复行而另一个查询集没有重复行的问题。 (3认同)

Adr*_*ián 6

此替代方案不需要排序:

self.assertQuerysetEqual(qs1, list(qs2), ordered=False)
Run Code Online (Sandbox Code Playgroud)

请参阅断言参考.

注意:仅适用于django 1.4+.

  • 看一下[docs](https://docs.djangoproject.com/en/1.5/topics/testing/overview/#django.test.TestCase.assertQuerysetEqual)我想,你的例子会起作用.但它没有......看起来`repr` func仅应用于第一个非列表查询集,而对于第二个列表,它必须明确地应用.使用django 1.4.5:`qs1 = M.objects.all(); qs2 = M.objects.all()#(相同)`,`self.assertQuerysetEqual(qs1,list(qs2),ordered = False)`< - 失败; `self.assertQuerysetEqual(qs1,map(repr,qs2),ordered = False)`< - pass; (6认同)