Django order by count by date

Доброе утро!

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

Вот мои модели:

Class Post(models.Model):
    name = models.CharField(max_length=40, default=None, null=False)
    cover = models.CharField(max_length=100, default=None, null=True, blank=True)
    content = models.TextField(max_length=2000, default=None, null=False)

class VoteDate(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    date = models.DateTimeField(default=timezone.now)

Ближе всего я подошел, но ничего не получилось, вот эта строка:

hot_today = Post.objects.annotate(count=Count('votedate', filter=Q(votedate__date=datetime.today()))).order_by('count')[:30]

Спасибо за помощь!

Здесь есть две проблемы: (1) вы фильтруете по полю date объектов VoteDate, которое является DateTime, следовательно, фильтрация не будет работать правильно, поскольку вы сравниваете объект datetime с объектом datetime с часами, минутами и секундами, установленными на ноль; и (2) вы должны упорядочивать в порядке убывания, поэтому -count, а не count:

from django.db.models import Q
from django.utils.timezone import now

hot_today = Post.objects.annotate(
    count=Count('votedate', filter=Q(votedate__date__date=now().date()))
).order_by('-count')[:30]

Возможно, вы захотите добавить индекс базы данных на поле date для повышения эффективности, и фильтровать в поле QuerySet:

class VoteDate(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    date = models.DateTimeField(auto_now_add=True, db_index=True)

мы можем фильтровать с помощью:

from django.db.models import Q
from django.utils.timezone import now

hot_today = Post.objects.filter(
    votedate__date__date=now().date()
).annotate(
    count=Count('votedate')
).order_by('-count')[:30]

Это не покажет Post, у которых нет голосов в этот день, но это может не быть проблемой. Фильтрация позволит эффективно сократить время запроса до только VoteDate, установленных на этот день.

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