【问题标题】:Django: union of different queryset on the same modelDjango:同一模型上不同查询集的联合
【发布时间】:2011-03-19 01:29:16
【问题描述】:

我正在对模型进行搜索,但遇到了问题。

我的模型几乎是这样的:

class Serials(models.Model):
    id = models.AutoField(primary_key=True)
    code = models.CharField("Code", max_length=50)
    name = models.CharField("Name", max_length=2000)

我在数据库中有这样的元组:

1   BOSTON   The new Boston
2   NYT      New York journal
3   NEWTON   The old journal of Mass
4   ANEWVIEW The view of the young people

如果我搜索字符串new,我想要的是:

  • 首先是以字符串开头的names
  • 然后是以字符串开头的codes
  • 然后是包含字符串的names
  • 然后是包含字符串的codes

所以前面的列表应该是这样出现的:

2   NYT      New York journal
3   NEWTON   The old journal of Mass
1   BOSTON   The new Boston
4   ANEWVIEW The view of the young people

我发现获得这种结果的唯一方法是进行不同的搜索(如果我在单个搜索中输入“OR”,我会失去我想要的顺序)。

我的问题是显示结果的模板代码确实是多余的,老实说非常丑陋,因为我必须为所有 4 个不同的查询集重复相同的代码。更糟糕的是我不能使用分页!

现在,由于不同查询集的结构是相同的,我正在徘徊是否有办法加入 4 个查询集并只给模板一个查询集。

【问题讨论】:

  • 从 1.11 版本开始,django 查询集有一个内置的 union 方法。我已将其添加为将来参考的答案

标签: django django-templates django-queryset


【解决方案1】:

您可以进行这四个查询,然后将它们链接到您的程序中:

result = itertools.chain(qs1, qs2, qs3, qs4)

但这似乎不太好,因为您必须进行查询。

您也可以使用原始sql编写自己的sql,例如:

Serials.objects.raw(sql_string)

也看看这个:

How to combine 2 or more querysets in a Django view?

【讨论】:

  • 另一种解决方案是完美的!
【解决方案2】:

您也应该能够做到qs1 | qs2 | qs3 | qs4。然而,这会给你重复。

您可能想要查看的是Q() 对象:

from django.db.models import Q
value = "new"
Serials.objects.filter(Q(name__startswith=value) |
                       Q(code__startswith=value) |
                       Q(name__contains=value) |
                       Q(code__contains=value).distinct()

如果你这样做,我不确定它是否会处理排序,因为这将依赖于 db 这样做。

确实,即使使用qs1 | qs2 也可能导致顺序由db 确定。这可能是缺点(也是您可能需要至少两个查询的原因)。

【讨论】:

  • 使用Q()对象会不会重复结果?
  • 那行代码比较长,但最后有一个.distinct()
  • 赞成使用 distinct。另一方面,使用 itertools 的答案实现了 SQL 'UNION ALL'。
  • 这是最好的答案——但应该注意的是,你不能用不同的 django 模型做到这一点。
猜你喜欢
  • 2018-04-24
  • 1970-01-01
  • 2018-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-27
  • 2011-01-08
相关资源
最近更新 更多