TLDR django の queryset API のメソッドのwhere
パラメーターをextra
使用すると、クエリに追加されるカスタム SQL を挿入できAND
ます。OR
クエリのリセットでその値を編集する必要がある状況があります。これに対するサポートはありますか?
別のテーブルとの M2M 関係を持つ大きなテーブルがあります
class BookName:
name = models.CharField(db_index=True)
other_names = models.ManyToManyField(OtherName)
class OtherBookName:
name = models.CharField(db_index=True)
リストからフルネームまたは別名を持つ本を照会したい。
自然に使用Q()
すると、物事がかなり遅くなります。
私の解決策は、リストに名前がある行を最初にクエリOtherBookName
し、それらの pks を返すことです (インデックスが作成されているため迅速です)。次に、2 つのモデルの間に手動で M2M テーブルを含め、テーブルで一致するインスタンスwhere
も抽出する必要がある句を追加します。BookName
test_names = ["Foo", "Bar",]
other_ids = OtherBookName.objects.filter(name__in=test_names).values_list("id", flat=True)
queryset = self\
.filter(Q(name__in=test_names)) \
.extra(
where=[
"bookname_id = app_bookname.id",
"booknameotherbookname_id IN (%s)"
% ",".join([str(id) for id in other_ids]),
],
tables=["app_bookname_otherbookname",]) \
.distinct()
これは、必要なときに where 句がAND
クエリに編集されることを除いて、ほとんど機能していますOR
。