filter(**kwargs) Returns a new QuerySet containing objects that match
the given lookup parameters.
The lookup parameters (**kwargs) should be in the format described in
Field lookups below. Multiple parameters are joined via AND in the
underlying SQL statement.
我认为它将返回原始集合中的项的子集。
然而,我似乎遗漏了一些东西,如下示例的行为与我预期的不同:>>> kids = Kid.objects.all()
>>> tuple(k.name for k in kids)
(u'Bob',)
>>> toys = Toy.objects.all()
>>> tuple( (t.name, t.owner.name) for t in toys)
((u'car', u'Bob'), (u'bear', u'Bob'))
>>> subsel = Kid.objects.filter( owns__in = toys )
>>> tuple( k.name for k in subsel )
(u'Bob', u'Bob')
>>> str(subsel.query)
'SELECT "bug_kid"."id", "bug_kid"."name" FROM "bug_kid" INNER JOIN "bug_toy" ON ("bug_kid"."id" = "bug_toy"."owner_id") WHERE "bug_toy"."id" IN (SELECT U0."id" FROM "bug_toy" U0)'
正如您在上面的subsel中看到的,结果返回了重复的记录,这不是我想要的。我的问题是,获取子集的正确方法是什么?(注意:按定义设置不会有同一对象的多个引用)
关于为什么的解释也很好,因为对我来说,filter意味着用Python中的内置函数filter()可以实现什么。也就是说:获取满足需求的元素(或者换句话说,丢弃不满足需求的元素)。这个定义似乎不允许引入/复制对象。
我知道完全可以distinct(),但这仍然会导致相当难看(而且可能比可能慢)的查询:>>> str( subsel.distinct().query )
'SELECT DISTINCT "bug_kid"."id", "bug_kid"."name" FROM "bug_kid" INNER JOIN "bug_toy" ON ("bug_kid"."id" = "bug_toy"."owner_id") WHERE "bug_toy"."id" IN (SELECT U0."id" FROM "bug_toy" U0)'
Mymodels.py完整性:from django.db import models
class Kid(models.Model):
name = models.CharField(max_length=200)
class Toy(models.Model):
name = models.CharField(max_length=200)
owner = models.ForeignKey(Kid, related_name='owns')
编辑:
在与@limelight聊天之后,我们得出的结论是,我的问题是我希望filter()按照字典的定义进行操作。也就是说,它在Python或任何其他理智的框架/语言中是如何工作的。
更准确地说,如果我设置了A = {x,y,z}并调用了A.filter( ),我就不会期望任何元素被复制。但对于Django的QuerySet,它的行为如下:A = {x,y,z}
A.filter( )
# now A i.e. = {x,x}
因此,首先问题是方法名不合适(类似于match()的方法会更好)。
第二件事是,我认为创建比Django允许的更有效的查询是可能的。我可能是错的,如果我有一点时间,我可能会试图检查这是否是真的。