Функция пользовательских аннотаций Django

Я хочу создать простой список горячих вопросов с помощью Django. У меня есть функции что оценивает "жар " каждого вопроса, основанного на некоторых аргументах.

функция выглядит аналогично этому (полная функция здесь)

def hot(ups, downs, date):
    # Do something here..
    return hotness

мои модели для моделей вопросов и голосования (соответствующая часть)

class Question(models.Model):
    title = models.CharField(max_length=150)
    body = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)

class Vote(models.Model):
    question = models.ForeignKey(Question, related_name='questions_votes')
    delta = models.IntegerField(default=0)

и delta attribute - это положительные или отрицательные. Функция hot получает количество положительных голосов и число отрицательных голосов и даты создания вопроса.

Я пробовал нечто подобное, но это не работает.

 questions = Question.objects.annotate(hotness=hot(question_votes.filter(delta, > 0),question_votes.filter(delta < 0), 'created_at')).order_by('hotness')

ошибка, которую я получаю:global name 'question_votes' is not defined
Я понимаю ошибку, но у меня нет правильного способа сделать это.

1 ответов


вы не можете использовать функции python для аннотаций. Аннотация-это вычисление, которое выполняется на уровне базы данных. Django предоставляет вам только набор базовых вычислений, которые могут быть обработаны базой данных-SUM, AVERAGE, MIN, MAX и так далее... Для более сложных материалов только с версии 1.8 у нас есть API для более сложных выражения запросов. До Django 1.8 единственным способом достижения подобной функциональности было использование .экстра что означает написать простой язык SQL.

таким образом, у вас в основном есть два с половиной варианта.

первые полтора.

напишите свое вычисление горячности в простом SQL, используя .extra или через новый API, если ваша версия Django >= 1.8.

второй.

создайте поле горячности внутри модели, которое будет рассчитываться заданием cron один раз в день (или чаще в зависимости от ваших потребностей). И используйте его для своих нужд (самый горячий список).