Django:同一模型上不同查询集的联合

Django: union of different queryset on the same model

我正在对一个模型进行搜索编程,但有一个问题。

我的模型几乎是:

1
2
3
4
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
2
3
4
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

因此,上一个列表应按以下方式显示:

1
2
3
4
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

我发现获得这种结果的唯一方法是进行不同的搜索(如果我在一次搜索中放入"或",我会松开我想要的顺序)。

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

现在,由于不同查询集的结构是相同的,所以如果有一种方法可以连接4个查询集,并且只给模板一个查询集,那么我将漫游。


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

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

但这似乎不太好,因为你必须提出疑问。

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

1
Serials.objects.raw(sql_string)

另请看这个:

如何在django视图中组合2个或多个查询集?


您还应该能够执行qs1 | qs2 | qs3 | qs4。不过,这会给你提供副本。

您可能希望查看的是Q()对象:

1
2
3
4
5
6
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()

如果你这样做的话,我不确定它是否能处理订单,因为这将依赖于数据库。

事实上,即使使用qs1 | qs2也可能导致由争端裁决委员会决定命令。这可能是缺点(也是您可能需要至少两个查询的原因)。