Django自定义注释功能 [英] Django custom annotation function

查看:120
本文介绍了Django自定义注释功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用Django构建一个简单的热点问题列表。我有一个功能,根据每个问题的热度评估一些论据。



功能看起来与此类似(全功能这里

  def hot(ups,downs,date):
#在这里做某事..
返回热度

我的问题和投票模型(相关部分)

  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属性是正或负。热门功能获得正面投票数量和负面投票数量和创建日期。



我已经尝试过这样的事情,但它不工作。 / p>

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

'得到的是:全局名称'question_votes'未定义

我明白错误,但我不是正确的方法。

解决方案

您不能使用python函数进行注释。注释是在数据库级别完成的计算。 Django只提供一组基本的计算,可以由数据库(SUM,AVERAGE,MIN,MAX等)处理...对于更复杂的东西,只有1.8版本,我们有一个更复杂的API 查询表达式。在Django 1.8之前,实现类似功能的唯一方法是使用 .extra ,这意味着写简单的SQL。



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



一个半。



使用在纯SQL中编写您的热度计算。额外的或通过新的API,如果你的Django版本是> = 1.8。



第二。



在你的模型里创建热点,这将由cron工作一天一次计算(或更多时候取决于您的需要)。并将其用于您的需求(最热门的列表)。


I want to build a simple hot questions list using Django. I have a function that evaluates "hotness" of each question based on some arguments.

Function looks similar to this (full function here)

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

My models for question and vote models (relevant part)

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)

Now, the delta attribute is either positive or negative. The hot function receives number of positive votes and number of negative votes and creation date of question.

I've tried something like this, but it isn't working.

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

The error I'm getting is: global name 'question_votes' is not defined
I understand the error, but I don't the correct way of doing this.

解决方案

You can't use python functions for annotations. Annotation is a computation that is done on a database level. Django provides you only a set of basic computations which can be processed by the database - SUM, AVERAGE, MIN, MAX and so on... For more complex stuffs only from version 1.8 we have an API for more complex query expressions. Before Django 1.8 the only way to achieve similar functionality was to use .extra which means to write plain SQL.

So you basically have two and a half options.

First and a half.

Write your hotness computation in plain SQL using .extra or via the new API if your Django version is >= 1.8.

Second.

Create hotness field inside you model, which will be calculated by a cron job once a day (or more often depending on your needs). And use it for your needs (the hottest list).

这篇关于Django自定义注释功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆