Django: объединение разных наборов запросов на одной модели - PullRequest
2 голосов
/ 21 июля 2010

Я программирую поиск по модели, и у меня проблема.

Моя модель почти как:

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

Единственный способ, с помощью которого я нашел такой результат, - это выполнять разные поиски (если я в одном поиске введу «ИЛИ», я потеряю нужный мне порядок).

Моя проблема в том, что код шаблона, который показывает результат, действительно избыточен и, честно говоря, очень уродлив, потому что мне приходится повторять один и тот же код для всех 4 различных наборов запросов. И хуже всего то, что я не могу использовать нумерацию страниц!

Теперь, так как структура различных наборов запросов одинакова, я берусь за возможность объединить 4 набора запросов и дать шаблону только один набор запросов.

Ответы [ 2 ]

7 голосов
/ 21 июля 2010

Вы можете сделать эти четыре запроса и затем связать их внутри вашей программы:

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

но это нехорошо, потому что вы должны делать запросы.

Вы также можете написать свой собственный sql, используя raw sql, например:

Serials.objects.raw(sql_string)

Также посмотрите на это:

Как объединить 2 или более набора запросов в представлении Django?

5 голосов
/ 09 января 2012

Вы также должны быть в состоянии сделать 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()

Я не уверен, будет ли он обрабатывать порядок, если вы сделаете это таким образом, так как это будет зависеть от того, как это сделает БД.

Действительно, даже использование qs1 | qs2 может привести к тому, что порядок будет определяться БД. Это может быть недостатком (и причиной, по которой вам может потребоваться как минимум два запроса).

...