Функция пользовательских аннотаций 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 один раз в день (или чаще в зависимости от ваших потребностей). И используйте его для своих нужд (самый горячий список).