#django #django-rest-framework #orm
Вопрос:
Есть два поля: start_date и end_date. (Поле даты).
Стандарт для сортировки.
- Как start_date, так и end_date являются пустыми значениями. (дата начала = Null, дата окончания = Null)
- Начальная дата последнего времени и конечная дата-это пустые значения (начальная дата = не null, конечная дата = Null)
- Если и start_date, и end_date имеют значения, последнее значение end_date (start_date = не Null, end_date = не Null)
- Если и start_date, и end_date имеют значения, start_date последний раз (start_date = не Null, end_date = не Null)
Например) Я хочу
start end 1. null null 2. null null 3. 2021-10-01 null 4. 2021-09-01 null 5. 2021-09-15 21-09-20 6. 2021-09-01 2021-09-20 7. 2021-09-01 2021-09-15
Я пытался
Model.objects.annotate( order1=Case( When(Q(start_date__isnull=True) amp; Q(end_date__isnull=True), then=0), When(Q(start_date__isnull=False) amp; Q(end_date__isnull=True), then=1), # how to order by start_date ?? When(Q(start_date__isnull=False) amp; Q(end_date__isnull=False), then=2), # how to order by end_date ?? output_field=IntegerField() ), ).order_by('order1')
Результат
start end 1. null null 2. null null 3. 2021-09-01 null # change 3, 4 4. 2021-10-01 null 5. 2021-09-15 21-09-20 6. 2021-09-01 2021-09-20 7. 2021-09-01 2021-09-15
Как я могу решить сложную задачу в django?
Комментарии:
1. поделитесь своими моделями?
2. Я не поделился моделью, потому что не рассматриваю поля, отличные от start_date и end_date.
3. Я сам нашел ответ. Как вы можете видеть из кода, order1-это просто аннотация. Спасибо 🙂
Ответ №1:
Я нашел способ работать, хотя скорость низкая. Это не было полностью проверено.
Model.objects.annotate( order1=Case(When(Q(start_date__isnull=True) amp; Q(end_date__isnull=True), then=1), default=0, output_field=IntegerField()) ).annotate( order2=Case(When(Q(start_date__isnull=False) amp; Q(end_date__isnull=True), then=Max('start_date')), output_field=DateField()) ).annotate( order3=Case(When(Q(start_date__isnull=False) amp; Q(end_date__isnull=False), then=Max('end_date')), output_field=DateField()) ).order_by( F('order1').desc(nulls_last=True), F('order2').desc(), F('order3').desc(), '-start_date' )
Я не думаю, что это идеальное решение, но я делюсь им, потому что это может кому-то помочь.
Если есть лучший способ, пожалуйста, поделитесь им.