比较django测试用例中的查询集

比较django测试用例中的查询集,django,compare,testcase,django-queryset,Django,Compare,Testcase,Django Queryset,我有一个非常简单的观点如下 def simple_view(request): documents = request.user.document_set.all() return render(request, 'simple.html', {'documents': documents}) 为了在我的测试用例中测试上面的视图,我使用了下面的错误排除方法 Class SomeTestCase(TestCase): # ... def test_simple_v

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

def simple_view(request):
    documents = request.user.document_set.all()
    return render(request, 'simple.html', {'documents': documents})
为了在我的测试用例中测试上面的视图,我使用了下面的错误排除方法

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
    # ...
我得到的错误是
AssertionError:False不是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

如果queryset对象是不同查询的结果,即使它们的结果中的值相同(比较
ds1.query
ds2.query

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


找到了解决办法。我们需要将
查询集
转换为排序列表,然后才能进行比较。事情如下

Class SomeTestCase(TestCase):
    # ...
    def test_simple_view(self):
        # ... some other checks
        docset1 = self.resonse.context['documents']
        docset2 = self.user.document_set.all()
        self.assertTrue(list(sorted(docset1)) == len(sorted(docset)))
    # ...

此备选方案不需要排序:

self.assertQuerysetEqual(qs1, list(qs2), ordered=False)


注意:仅适用于django 1.4+。

适用于me的
转换
选项:

    def subject(self):
        return Mission.objects.add_keynest_api_token().filter(keynest_api_token__isnull=False)

    def test_mission_has_property(self):
        self.mission.appartement = self.property
        self.mission.save()
        self.assertQuerysetEqual(self.subject(), [self.mission], transform=lambda x: x)


尝试过这一点,但查询集并非总是相等的(即使它们是相同的)!使用:
self.assertquerystequal(qs1,map(repr,qs2),ordered=False)
。从这条线:@stable我真的不知道为什么。。。默认情况下,应该使用
repr()
进行比较。如果两个quesysets相等,那么repr应该是相同的,对吗?看看我的想法,你的例子就行了。但它不。。。看起来
repr
func仅应用于第一个非列表查询集,而对于第二个列表,必须显式应用它。对于django 1.4.5:
qs1=M.objects.all();qs2=M.objects.all()#(相同)
self.assertquerystequal(qs1,list(qs2),ordered=False)
Yes
assertquerystequals
在2.1中失败,即使传递了相同的queryset引用,例如,
assertquerystequals(qs1,qs1)
——但stape的解决方案确实有效。或者更简洁地说,self.assertEqual(list(ds1),list(ds2))如果您的查询集太大,无法进行计算,那么您可能可以使用django,或者我们可以使用
set()
,而不是
list()
,以独立于排序顺序。True,可以将它们放在一个集合中,但这也可能隐藏一个查询集合有重复行,而另一个查询集合没有重复行的问题。@MattiJohn:你完全正确。事实上,我自己也遇到了这样的问题。我将坚持使用
list()
。谢谢
    def subject(self):
        return Mission.objects.add_keynest_api_token().filter(keynest_api_token__isnull=False)

    def test_mission_has_property(self):
        self.mission.appartement = self.property
        self.mission.save()
        self.assertQuerysetEqual(self.subject(), [self.mission], transform=lambda x: x)