Таким образом, я вытягиваю список ссылок, и я пытаюсь отсортировать эти ссылки по популярности. Я использую алгоритм Hacker News:
Y Combinator's Hacker News: Popularity = (p - 1) / (t + 2)^1.5 Votes divided by age factor. Where p : votes (points) from users. t : time since submission in hours. p is subtracted by 1 to negate submitter's vote. Age factor is (time since submission in hours plus two) to the power of 1.5.factor is (time since submission in hours plus two) to the power of 1.5.
Я выполнил это в MySQL и Платформе PHP при помощи порядка
(SUM(votes.karma_delta) - 1) / POW((TIMESTAMPDIFF(HOUR, links.created, NOW()) + 2), 1.5) DESC
Теперь я использую PostgreSQL и Django. Я знаю, что этот точный SQL, вероятно, не будет работать, но я могу сделать преобразование позже. Проблема, с которой я сталкиваюсь, я не знаю, как получить такой комплекс order_by в Django. Мое представление имеет идеальное:
popular_links = Link.objects.select_related().annotate(karma_total = Sum('vote__karma_delta'))
И я действительно не хочу пачкать это при помощи сырых данных sql, если я не имею к.
Суммировать мой вопрос: как я могу создать комплекс order_by в Django?
Править
Будет разбиение на страницы, и я действительно только хочу отсортировать записи, которые я вытягиваю. Просто лучше на самом деле сделать ту сортировку в Python?
Нет чистого способа, кроме как использовать extra() с вашим пользовательским SQL:
popular_links = Link.objects.select_related().annotate(karma_total = Sum('vote__karma_delta'))
popular_links = popular_links.extra(
select = {'popularity': '(karma_total - 1) / POW((TIMESTAMPDIFF(HOUR, links.created, NOW()) + 2), 1.5)',},
order_by = ['-popularity',]
)
Если вы все равно собираетесь вытаскивать весь список (то есть, например, вы берете не только первые 10 записей), то сортировку можно выполнить на Python.
.