объект datetime.date не вызывается - PullRequest
1 голос
/ 17 июня 2020

У меня есть модель с полем date и следующий метод:

class Pm(models.Model):
    mydate = models.DateField()

    @property
    def due_date(self):
        today = timezone.localtime(timezone.now()).date()
        if self.mydate < today:
            return today
        else:
            return self.mydate

Как я могу заказать myModel.objects.all() на основе возврата функции due_date? Я пробовал:

qs = sorted(Pm.objects.all(), key=lambda a: a.due_date(), reverse=True)

, но он возвращает ошибку:

'datetime.date' object is not callable

ОБНОВЛЕНИЕ На основе предложения Сами:

@staticmethod
    def due_date(obj):
        today = timezone.localtime(timezone.now()).date()
        if obj.pm_date < today:
            return today
        else:
            return obj.pm_date

qs = sorted(Pm.objects.all(), key=Pm.due_date, reverse=True)

Кажется, работает , за исключением того, что он возвращает list вместо queryset. Какой метод мне следует использовать, чтобы получить queyset?

Ответы [ 2 ]

2 голосов
/ 17 июня 2020

Честно говоря, я бы не стал сортировать по python. По двум причинам:

  • База данных должна делать это лучше / быстрее, чем python
  • Это свойство делает многие даты не сортируемыми: все, что старше сегодняшнего, становится равным. Это бесполезно, особенно без вторичного поля сортировки.

И поскольку вам в конечном итоге нужен набор запросов, просто сохраняйте его:

2 голосов
/ 17 июня 2020

Я думаю, вам нужно сделать свой метод due_date методом c или отделить его от модели, метод получает объект и возвращает дату, а затем использовать этот метод в отсортированном методе. Примерно так

def due_date(obj):
        today = timezone.localtime(timezone.now()).date()
        if obj.date < today:
            return today
        else:
            return obj.date
qs = sorted(Pm.objects.all(), key=due_date, reverse=True)

Если вы сделаете этот метод stati c в классе Model, то используйте его как:

qs = sorted(Pm.objects.all(), key=PM.due_date, reverse=True)

В противном случае вам нужно аннотировать, а затем использовать order_by of набор запросов. аннотация с условными выражениями F-выражения

что-то вроде этого (это может быть не точное решение, но вам нужно сделать что-то вроде этого):

from django.db.models import Case, DateField, Value, When
qs = Pm.objects.annotate(
    due_date=Case(
        When(date__lt=today, then=Value(today)),
        default=F("date"),
        output_field=DateField(),
    )
)
qs.order_by("due_date")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...