django order_by с использованием условного - PullRequest
0 голосов
/ 08 января 2020

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

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

class Project(models.Model):
    '''
    Main Project, serves the default Projects Portal window.
    '''
    published = models.DateTimeField(auto_now_add=True)
    user = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
    area = models.ForeignKey(
        Area,
        related_name="project",
        on_delete=models.PROTECT
        )
    title = models.CharField(max_length=128, unique=True)
    slug = models.SlugField(max_length=64)
    summary = models.CharField(max_length=256)
    others = models.CharField(max_length=128, blank=True)
    staff_trials = models.DateField(null=True, blank=True)
    deadline = models.DateField()
    slip = models.BooleanField(default=False)

    class Meta:
        ordering = ["-slip", "staff_trials", "deadline"]

    def __str__(self):
        return self.title

Это было немного удар в темноте, чтобы надеяться, что это сработает, но это просто ставит все staff_trials на первое место, что не совсем то, что мне нужно, мне нужно, чтобы сами даты были в порядке, например,

project A - deadline - 12/01/2020
project B - staff_trials - 15/01/2020 deadline - 01/02/2020
project C - deadline - 20/01/2020
project D - deadline - 23/01/202

это будет порядок, и после 15-го числа проект B появится внизу этого списка. Есть ли способ сделать это?

1 Ответ

1 голос
/ 08 января 2020

Я думаю, что вы, возможно, не сможете определить этот порядок для мета-класса модели, но при фильтрации экземпляров вы можете придерживаться следующего подхода:

Projects.objects.annotate(
    actual_deadline=Case(
        When(staff_trials__isnull=True, then=F('deadline')),
        When(staff_trials__isnull=False, then=F('staff_trials')),
        output_field=DateTimeField(),
    )
).order_by('actual_deadline')

Здесь мы аннотируем каждый результат с помощью DateTimeField с именем «actual_deadline», получая значение val ie staff_trials, если оно определено, поле крайнего срока, если оно не определено. Затем мы упорядочиваем результаты в этом поле.

Я не тестировал код, но должен работать с некоторыми настройками, если не напрямую.

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