обеспечить строки по приоритету в Django - PullRequest
0 голосов
/ 30 сентября 2019

У меня есть следующая модель в django:

class task(models.Model):
    admin = models.BooleanField()
    date = modesl.DateField()

Я пытаюсь создать фильтр, который предоставляет мне набор запросов, который устанавливает приоритеты, если admin = True

Итак, предположим, у меня есть эти3 строки:

admin = True , date = 01-01-2019
admin = False , date = 01-01-2019
admin = False , date = 02-02-2019

Выводом набора запросов будет:

admin = True , date = 01-01-2019
admin = False , date = 02-02-2019

, он должен отфильтровать строку с 01-01-2019, который admin = False, поскольку уже существуетadmin = Истинная строка, которая должна иметь приоритет.

Я мог бы сделать это, выбрав все и удалив его из query_set самостоятельно, но хочу убедиться, что другого способа сделать это раньше нет.

Ответы [ 2 ]

2 голосов
/ 30 сентября 2019

Вместо того, чтобы перебирать QuerySet и удалять их самостоятельно, одну вещь, которую вы могли бы сделать, это:

  1. Получить все даты, где admin равен True
  2. Получить все объектыгде либо: я. Администратор True II. Дата не входит в часть 1 (например, admin - False)

Это может быть достигнуто с помощью следующего:

from django.db.models import Q

true_dates = task.objects.filter(admin=True).values_list("date", flat=True)
results = task.objects.filter(Q(admin=True)|~Q(date__in=true_dates))

Это, скорее всего, будет более эффективным, чем зацикливаниесвоими результатами.

Обратите внимание, что поскольку наборы запросов являются «ленивыми» (это означает, что оцениваются только тогда, когда они абсолютно необходимы), это приведет к попаданию всего в 1 дБ

1 голос
/ 30 сентября 2019

Ответ Тима близок, но неполон, потому что он не использует Subquery().

Этот ответ дает те же результаты, но при этом дополнительный запрос не попадает в базу данных:

from django.db.models import Subquery, Q

dates = Task.objects.filter(admin=True)
tasks = Task.objects.filter(Q(admin=True) | ~Q(date__in=Subquery(dates.values('date')))
...