私は次のDjangoモデルを持っています:
class Make:
name = models.CharField(max_length=200)
class MakeContent:
make = models.ForeignKey(Make)
published = models.BooleanField()
すべてのMake
sおよび関連するMakeContent
sがpublished = True
であるクエリセットを生成できるかどうか(SQLを直接記述することなく)知りたいのですが。
Djangoは、外部キーの逆引き参照のためのselect_related()
メソッドをサポートしていないため、Pythonを残さずにできる最善の方法は、2つのデータベースクエリです。 Makes
を含むMakeContents
ここで、published = True
、2番目はすべての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」を含めることができます。
質問者が「作成」を照会することを意味する場合 少なくとも一つの published = Trueの 'MakeContent'の場合、Jason Christaの2番目のスニペットが質問に答えます。
スニペットは次と同等です
makes = Make.objects.select_related().filter(makecontent__published=True).distinct()
しかし、質問者が「Make」を照会することを意味する場合 すべて published = Trueである「MakeContent」、上記の「makes」に続いて、
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)
それが役立つことを願っています。