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

时间:2010-07-21 15:05:30

标签: django django-templates django-queryset

我正在编写模型搜索,但我遇到了问题。

我的模特几乎就像:

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个查询集并且只给模板一个查询集,我就会徘徊。

2 个答案:

答案 0 :(得分:7)

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

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?

答案 1 :(得分:5)

您还应该能够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确定。这可能是缺点(以及您可能至少需要两次查询的原因)。