Django自定义注释功能

时间:2015-05-23 18:36:41

标签: python django django-queryset

我想使用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
我理解错误,但我没有正确的方法。

2 个答案:

答案 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