Django的Queryset与反向外键过滤
我有以下的Django模型:
class Make: name = models.CharField(max_length=200) class MakeContent: make = models.ForeignKey(Make) published = models.BooleanField()
我想知道是否有可能(无需直接编写SQL)生成一个查询集,其中包含所有的Make
和每个相关的MakeContent
,其中published = True
。
Django不支持用于反向外键查找的select_related()方法,所以在不离开Python的情况下可以做的最好的是两个数据库查询。 首先是抓取包含MakeContents的所有Make其中published = True,第二个抓取所有MakeContents其中published = True。 然后,你必须循环,并安排你想要的数据。 这里有一个关于如何做到这一点的好文章:
http://blog.roseman.org.uk/2010/01/11/django-patterns-part-2-efficient-reverse-lookups/
是的,我想你想要
make = Make.objects.get(pk=1) make.make_content_set.filter(published=True)
或者可能
make_ids = MakeContent.objects.filter(published=True).values_list('make_id', flat=True) makes = Make.objects.filter(id__in=make_ids)
让我把斯派克的措辞回答翻译成未来观众的代码。 请注意,每个“Make”可以有零个到多个“MakeContent”
如果提问者的意思是用“ 至less一个 ”“MakeContent”查询“Make”,其出版物= True,那么Jason Christa的第二个片段就可以回答这个问题。
片段相当于
makes = Make.objects.select_related().filter(makecontent__published=True).distinct()
但是,如果提问者的意思是查询所有 'MakeContent'的发布= True的'Make',那么遵循上面的'make'
import operator make_ids = [m.id for m in makes if reduce(operator.and_, [c.published for c in m.makecontent_set.all()] ) ] makes_query = Make.objects.filter(id__in=make_ids)
包含所需的查询。
我知道这是一个很老的问题,但我正在回答。 我想我的答案可以帮助别人。 我已经改变了一下模型。 我用Django 1.8。
class Make(models.Model): name = models.CharField(max_length=200) class MakeContent(models.Model): make = models.ForeignKey(Make, related_name='makecontent') published = models.BooleanField()
我已经使用了下面的查询集。
Make.objects.filter(makecontent__published=True)
希望它会有所帮助。