Есть ли в Django способ упорядочить модель с помощью "пользовательской логики фильтрации"?

В настоящее время у меня возникла проблема в личном проекте, который включает в себя упорядочивание по 2 пользовательским полям (limit_date и priority). Предположим, что модель выглядит следующим образом:

PRIORITY_CHOICES = [
        ("red", "Red"),
        ("yellow", "Yellow"),
        ("green", "Green")
    ]

class Todo(models.Model):
    limit_date = models.DateField()
    priority = models.CharField(choices=PRIORITY_CHOICES, max_length=15,         
                                blank=False, null=True)

Предположим, я хочу упорядочить их, следуя следующей логике:

if <current_todo>.priority == 'red':
    priority_scale = 3
elif <current_todo>.priority == 'yellow':
    priority_scale = 2
else:
    priority_scale = 1

priority_scale_with_date = <current_todo>.limit_date - datetime.today() * (<current_todo>.priority_scale)

Я знаю, что могу делать некоторые вещи с "условными выражениями" для получения приоритетов в качестве значений, например:

Todo.objects.annotate(
    priority_scale=Case(
        When(priority='red',
            then=Value(3)),
        When(priority='yellow',
            then=Value(2)),
        When(priority='green',
            then=Value(1)),
        default=Value(0),
        output_field=models.IntegerField())).order_by('-priority_scale', 'limit_date')

Но я не знаю, как я могу соединить их все "вместе". Допустим, объект с приоритетом "красный" (значение 3), у которого осталось два дня, и другой объект с приоритетом "зеленый" (значение 1), у которого остался один день. Их приоритеты будут примерно такими: first_obj = 1 * 3 = 3 (дни до limit_date и 'priority_scale') second_obj = 2 * 1 = 2 (дни до limit_date и 'priority_scale'). Что я хочу, так это упорядочить их с "пересечением" 'priority_scale' и 'limit_date'. Я очень запутался и прошу прощения за этот очень плохой текст.

Я бы предположил, что это случай для хранения значения на уровне базы данных как целого числа, и создания метода модели для представления его представлениям и пользователям как "красный" и т.д.

PRIORITY_CHOICES = [
    (3, "Red"),
    (2, "Yellow"),
    (1, "Green"),
    (0, "Null")
]
priority = models.IntegerField(choices=PRIORITY_CHOICES, max_length=15,         
     )  # default=0 ? 

In views `todo_instance.get_priority_display()` will return `"Red"` etc.

Где я не могу помочь, так это как получить количество оставшихся дней на уровне базы данных, чтобы можно было вычислить значение для annotate и order_by с помощью F-выражений. (Я просмотрел функции базы данных , но не могу сразу понять, как сделать разницу дат. Я думаю "это должно быть возможно"...)

Вернуться на верх