Сортировать запрос Python Django сначала всегда с нуля, затем с положительным, затем с отрицательным - PullRequest
0 голосов
/ 04 декабря 2018

У меня есть объекты Django, настроенные так:

class Example(models.Model):
    count = models.CharField(default="0")

Так что, если у меня есть какие-то объекты ex1, ex2, ex3, ex4 со счетчиком -1, 0,5, -6 соответственно.Я хочу иметь возможность запрашивать объекты и сортировать их в порядке [0, 5, -6, -1], где сначала идут любые нули, затем положительные значения, затем отрицательные значения, а также в порядке возрастания для каждого раздела.Я думал об использовании чего-то вроде Example.objects.order_by('count'), но не нашел способа сделать это с помощью пользовательской функции, такой как this .

Другой маршрут, на который я смотрел, был примерно таким:

objs = Example.objects.all()
sorted_objs = sorted(objs, key = lambda o: int(o.count))

Есть ли способ использовать отсортированный метод для сортировки нулей в первую очередь?Я не смог его найти.

Последний способ, которым я пользуюсь:

objs = Example.objects.all()
zero_objs = []
positive_objs = []
negative_objs = []
for obj in objs:
    if obj.count == 0:
        zero_objs.append(obj)
    elif obj.count < 0:
        negative_objs.append(obj)
    else:
        postitive_objs.append(obj)
sorted_objs = zero_objs + sorted(postitive_objs) + sorted(negative_objs)

Это работает, но кажется, что это не лучший способ сделать это, поэтому любые идеи будут хороши,В качестве примечания, я знаю, что атрибут count лучше хранить в виде целочисленного поля, но я хотел бы добиться этого, сохраняя при этом поле char.

1 Ответ

0 голосов
/ 04 декабря 2018

Вы можете использовать case, чтобы добавить новое поле для целей заказа:

>>> from django.db.models import Case, IntegerField, Value, When
>>> Example.objects.annotate(
...     o=Case(
...         When(count=0, then=Value(0),
...         When(count__gt=0, then=Value(1)),
...         When(count__lt=0, then=Value(2)),
...         output_field=IntegerField(),
...     ),
... ).order_by('o', 'count')

Объяснение:

Предложение Order будетбыть составленным из: «нового поля», count.С помощью «нового поля» вы поднимаете множество строк с числом = 0 на вершину, а затем множество положительных чисел на последнем множестве отрицаний.Второе поле, count, выполняет сортировку по возрастанию для каждого набора.

Отказ от ответственности:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...