【发布时间】:2012-11-23 18:48:49
【问题描述】:
TLDR 使用where parameter of the extra method of django's queryset api 时,您可以将ANDed 的自定义SQL 插入到您的查询中。我有一种情况,我需要 ORed 和重置查询的值。对此有支持吗?
我有一个 大 表,它与另一个表具有 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(因为它已被索引,所以速度很快)。然后,我在两个模型之间手动包含 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()
这非常接近工作,除了当我想 OR 它时,我的 where claus 是 ANDed 到查询。
【问题讨论】:
-
您能否再次检查您发布的代码。
models.ManyToManyField(OtherNames)你的意思是OtherBookNames是这里的关系吗? -
还有
OtherBookNames.objects.filter(name__in=names)OtherBookNames表没有字段name它有names -
对不起 - 你是对的,变量不正确
-
对不起,我有点困惑。您希望额外的内部
where子句为OR,还是整个where子句为带有外部查询的OR?
标签: django django-orm