IN 句は遅いため (特に PostgreSQL では)、大きな IN 句を避けるのは良くないと読みました。
Fridge というクラスと、Vegetables and Condiments というクラスがあるとします。
これらは両方とも、それら自身と Fridge の間に ManyToMany 関係を持っています。
次のようなものです:
class Fridge(models.Model):
condiments = models.ManyToManyField(Condiments)
vegetables = models.ManyToManyField(Vegetables)
そして、ここに白い冷蔵庫を表す QuerySet があります。
qs = Fridges.objects.filter(color='white')
最初の質問:
「調味料 ID のリストが与えられたら、それらの調味料が入っているすべての冷蔵庫を取得してください (元の QuerySet を変更します)」。
2 番目のクエリ:
「野菜 ID のリストが与えられたら、それらの野菜がすべて入っているすべての冷蔵庫を取得します (元の QuerySet を変更します)。」
冷蔵庫 ID のリストを作成してクエリセットに IN 句を追加せずに、どうやってそれを行うのでしょうか?
IN句でそれを行うソリューションは次のとおりです(既存のソリューションの名前が変更されたバージョン):
最初のクエリ:
condiment_ids = [...] # list of condiment IDs
condiments = Condiment.objects.filter(
id__in=condiment_ids).all()
condiment_fridges = None
for condiment in condiments:
qs = condiment.fridge_set.all()
if not condiment_fridges:
condiment_fridges = qs
else:
condiment_fridges = condiment_fridges | qs
qs = qs.filter(id__in=[l.id for l in condiment_fridges])
2 番目のクエリ:
vegetable_ids = [...] # list of vegetable IDs
vegetables = vegetable.objects.filter(id__in=vegetable_ids).all()
vegetable_fridges = None
for vegetable in vegetables:
qs = vegetable.location_set.all()
if not vegetable_fridges:
vegetable_fridges = qs
else:
vegetable_fridges = vegetable_fridges & qs
qs = qs.filter(id__in=[l.id for l in vegetable_fridges])
これらのソリューションは恐ろしくハックに思えます.DjangoのORMでそれらを行うより良い方法があるかどうか疑問に思っていました.