如何检查obj是否在查询集中?
我试过了:
self.assertIn(obj, list(MyModel.objects.filter(...))
但它在我的情况下不起作用。
AssertionError: <MyModel 137 'unclassified'> not found in
[<MyModel 1676 'foo'>, ..., <MyModel 137 'unclassified'>, ...]
我不明白,因为它在列表中。
答案 0 :(得分:3)
怎么样
self.assertTrue(MyModel.filter(...).filter(pk=obj.pk).exists())
答案 1 :(得分:1)
首先,它应该是MyModel.objects.filter(...)
。如果你省略.objects
,你应该会得到一个不同的错误,所以我假设你确实包含了它,但在问题中忘了它。
如果obj
实际上在QuerySet
返回,那么你所做的应该是有效的,因为Django模型实例提供了一个相等的比较器,它比较了类型和主键。 list()
周围不需要QuerySet
,但如果您使用它,它仍然可以使用。
def __eq__(self, other):
return isinstance(other, self.__class__) and self._get_pk_val() == other._get_pk_val()
如果它仍然不起作用,可能有几个原因:
__eq__
方法并做了一些奇怪的事情。或者您使用一些自定义过滤器覆盖默认管理器.objects
。这种情况超出了这个答案的范围,如果你这样做,你应该知道如何解决它。为了帮助您诊断出是哪种情况,请尝试以下方法:
self.assertTrue(isinstance(obj, MyModel))
# 1. If it fails here, your object is an incorrect type
# Warning: the following tests can be very slow if you have a lot of data
self.assertIn(obj.pk, MyModel.objects.values_list('pk', flat=True))
# 2. If it fails here, the object doesn't exist in the database
self.assertIn(obj.pk, MyModel.objects.filter(...).values_list('pk', flat=True))
# 3. If it fails here, the object did not pass your filter conditions.
self.assertIn(obj, MyModel.objects.filter(...))
# 4. If it fails here, you probably messed with the Django ORM internals. Tsk tsk.
答案 2 :(得分:0)
请注意.all()
queryset_result = MyModel.filter(...).all()
if obj in queryset_result:
//obj is in the queryset
答案 3 :(得分:0)
“in”失败,因为对象实际上并不相等,因为默认情况下equ是对象标识。如果您希望“在”中工作,则必须在模型上相应地实施__eq__
。
如果您不想这样做,可以通过比较pk进行检查,如此
self.assertIn(obj.pk, [o.pk for o in MyModel.filter(...)])
答案 4 :(得分:0)
我认为这是非常简单的方法来查找queryset中存在的对象。
第一个例子:
obj_list = MyModel.filter(...)
if obj in obj_list:
print "obj in queryset"
else:
print "not in queryset"
第二个例子:
obj_list = MyModel.filter(...)
try:
obj_list.get(pk=obj.id)
except:
# If try get success obj is present in query set else your this except get executed.