Как добавить заказ в кейс, когда условия в django

#django #django-rest-framework #orm

Вопрос:

Есть два поля: start_date и end_date. (Поле даты).

Стандарт для сортировки.

  1. Как start_date, так и end_date являются пустыми значениями. (дата начала = Null, дата окончания = Null)
  2. Начальная дата последнего времени и конечная дата-это пустые значения (начальная дата = не null, конечная дата = Null)
  3. Если и start_date, и end_date имеют значения, последнее значение end_date (start_date = не Null, end_date = не Null)
  4. Если и 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'  )  

Я не думаю, что это идеальное решение, но я делюсь им, потому что это может кому-то помочь.

Если есть лучший способ, пожалуйста, поделитесь им.