【问题标题】:Django custom annotation functionDjango 自定义注解功能
【发布时间】:2015-08-05 15:09:45
【问题描述】:

我想使用 Django 构建一个简单的热点问题列表。我有一个function,它根据一些论点评估每个问题的“hotness”。

功能与此类似 (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
我理解错误,但我没有这样做的正确方法。

【问题讨论】:

    标签: python django django-queryset


    【解决方案1】:

    您不能将 python 函数用于注释。注释是在数据库级别完成的计算。 Django 只为您提供一组可由数据库处理的基本计算 - SUM、AVERAGE、MIN、MAX 等等……对于仅从 1.8 版开始的更复杂的东西,我们有一个用于更复杂query expressions 的 API。在 Django 1.8 之前,实现类似功能的唯一方法是使用.extra,这意味着编写普通 SQL。

    所以你基本上有两个半的选择。

    上半场。

    如果您的 Django 版本 >= 1.8,则使用 .extra 或通过新 API 以纯 SQL 编写您的热度计算。

    第二个。

    在您的模型中创建热度字段,该字段将由 cron 作业每天计算一次(或根据您的需要更频繁地计算)。并将其用于您的需求(最热门的列表)。

    【解决方案2】:

    对于那些寻找更新答案(Django 2.0+)的人,可以将 Func 子类化以根据 documentation 为聚合生成自定义函数。在“使用自定义数据库功能扩展”部分的帖子中,有一个很好的解释和示例 here 大约 80%。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-20
      • 1970-01-01
      • 2018-02-05
      • 1970-01-01
      相关资源
      最近更新 更多