我想使用Django构建一个简单的热门问题列表。我有function根据一些参数评估每个问题的“热度”。
功能类似于此(full function here)
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
是正面的还是负面的。热门职能获得正投票数,负投票数和问题创建日期。
我尝试过类似的东西,但它没有用。
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
我理解错误,但我没有正确的方法。
答案 0 :(得分:14)
您不能将python函数用于注释。注释是在数据库级别上完成的计算。 Django只为您提供了一组可以由数据库处理的基本计算 - SUM,AVERAGE,MIN,MAX等等...对于仅从1.8版开始的更复杂的东西,我们有一个更复杂的API query expressions 。在Django 1.8之前,实现类似功能的唯一方法是使用.extra,这意味着编写纯SQL。
所以你基本上有两个半选项。
如果您的Django版本是&gt; = 1.8,则使用.extra
或通过新API在纯SQL中编写热度计算。
在您的模型中创建热点字段,该字段将由cron作业每天计算一次(或者更多地根据您的需要进行计算)。并根据您的需要使用它(最热门的列表)。
答案 1 :(得分:0)
对于那些寻求更新答案的人(Django 2.0+),可以根据documentation将Func子类化以生成用于聚合的自定义函数。在“使用自定义数据库功能扩展”部分的帖子中,大约有80%的内容很好地解释了示例here。