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

Gio*_*lia 2 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)
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

如果我搜索字符串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
Run Code Online (Sandbox Code Playgroud)

我发现有这种结果的唯一方法是进行不同的搜索(如果我在一次搜索中输入"OR",我就会松开我想要的顺序).

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

现在,由于不同查询集的结构是相同的,如果有一种方法可以连接4个查询集并且只给模板一个查询集,我就会徘徊.

gru*_*czy 7

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

result = itertools.chain(qs1, qs2, qs3, qs4)
Run Code Online (Sandbox Code Playgroud)

但这似乎并不好,因为你必须进行查询.

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

Serials.objects.raw(sql_string)
Run Code Online (Sandbox Code Playgroud)

还看看这个:

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


Mat*_*kel 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()
Run Code Online (Sandbox Code Playgroud)

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

实际上,即使使用qs1 | qs2也可能导致订单由db确定.这可能是缺点(以及为什么您可能需要至少两个查询).