我有以下Django模型:
class Make:
name = models.CharField(max_length=200)
class MakeContent:
make = models.ForeignKey(Make)
published = models.BooleanField()
我想知道是否可以(不直接编写SQL)生成一个查询集,其中包含所有Make
和每个MakeContent
的{{1}}个published = True
。
答案 0 :(得分:54)
是的,我想你想要
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)
答案 1 :(得分:14)
让我将Spike的措辞答案翻译成未来观众的代码。请注意,每个'制作'可以有零到多个' MakeContent'
如果提问者意味着询问“制作”。 至少一个' MakeContent'发表的= True,然后是杰森克里斯塔的第二个片段回答了这个问题。
该代码段相当于
makes = Make.objects.select_related().filter(makecontent__published=True).distinct()
但是,如果提问者意味着询问“制作”。与 ALL ' MakeContent'发表的= True,然后跟随'制作'以上,
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)
包含所需的查询。
答案 2 :(得分:14)
我知道这是一个非常古老的问题,但我正在回答。我认为我的答案可以帮助别人。我已经改变了模型如下。我用过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)
希望它会有所帮助。
答案 3 :(得分:10)
Django不支持反向外键查找的select_related()
方法,因此在不离开Python的情况下,您可以做的最好的事情是两个数据库查询。第一种方法是抓取Makes
包含MakeContents
published = True
的所有MakeContents
,第二种方法是抓取所有published = True
{{1}}。然后,您必须循环并按您希望的方式排列数据。这是一篇关于如何做到这一点的好文章:
http://blog.roseman.org.uk/2010/01/11/django-patterns-part-2-efficient-reverse-lookups/
答案 4 :(得分:1)
再过一次,不清楚是什么问题,但是如果需要所有相关的MakeContent对象都已经发布,则可以这样做:
String
如果其中至少有一个(与其他答案一样):
Make.objects.exclude(MakeContent_set__published=False)