【问题标题】:ORing the 'where' clause values when using the 'extra' method of the ORM使用 ORM 的“extra”方法时对“where”子句值进行 ORing
【发布时间】: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


【解决方案1】:

试试这个:

names = ["Foo", "Bar",]
other_ids = OtherBookName.objects.filter(name__in=names).values_list("id", flat=True)
where_clause = "bookname_id = app_bookname.id AND (name IN (%s)" \
                % ",".join(names) + " OR booknameotherbookname_id IN (%s))" \
                % ",".join([str(id) for id in other_ids])
queryset = self\
            .extra(
                where=[where_clause],
                tables=["app_booknames_otherbookname",]) \
            .distinct()

【讨论】:

    猜你喜欢
    • 2021-05-20
    • 2010-11-06
    • 1970-01-01
    • 2010-11-13
    • 2014-01-17
    • 1970-01-01
    • 2020-10-27
    • 2015-03-13
    • 1970-01-01
    相关资源
    最近更新 更多