当前位置:  开发笔记 > 后端 > 正文

在Django模型中将NULL视为'0'

如何解决《在Django模型中将NULL视为'0'》经验,为你挑选了1个好方法。

我在我的Django应用程序中使用以下代码:

pictures = gallery.picture_set.annotate( score=models.Sum( 'picturevote__value' ) ).order_by( '-score' )

有一张画廊的桌子.在他们每个人都是一些图片.当用户向上或向下投票时,插入"picturevote"中的新行并连接到图片.然后我可以得到图片的总分.现在我想按照他们的分数来订购一个画廊的图片.但是由于表连接,当没有投票时,得分值可以为NULL.然而,分数'NULL'应被视为'0'.

有任何想法吗?

编辑:好的,这里有一些额外的解释:问题是上面例子中的聚合设置score为NULL.当我想显示分数时,我会使用以下内容:

score = self.picturevote_set.aggregate( models.Sum( 'value' ) )[ 'value__sum' ] or 0

然后聚合导致NULL(如果没有picturevote行)或某个值.如果为NULL,则or-expression将其转换为可显示的整数值.但这只解决了由NULL值引起的显示问题.当我想按照score第一个代码示例中的值对图片进行排序时,所有带NULL的条目都放在有序结果集的末尾.首先是有正分数的图片,然后有负值的图片,那么到目前为止没有投票或者没有投票的图片,因为它们是NULL score.

我的问题是如何改变这种行为,以便订单是正确的.



1> Jonny Buchan..:

在引入注释之前,您可能已经习惯extra了这样的事情,我认为应该0在没有投票的情况下返回(如果没有任何特定的数据库实现,您至少可以直接插入必要的COALESCE函数)调用 - COALESCE(SUM(value), 0)- 使用此方法):

pictures = gallery.picture_set.extra(
    select={
        'score': 'SELECT SUM(value) FROM yourapp_picturevote WHERE yourapp_picturevote.picture_id = yourapp_picture.id',
    },
    order_by=['-score']
)

我看不到任何内置的方法将自己的SQL添加到新的注释内容(我还没有亲自使用过),但看起来你应该能够像这样创建一个新的注释:

from django.db.models import aggregates
from django.db.models.sql import aggregates as sql_aggregates

class SumWithDefault(aggregates.Aggregate):
    name = 'SumWithDefault'

class SQLSumWithDefault(sql_aggregates.Sum):
    sql_template = 'COALESCE(%(function)s(%(field)s), %(default)s)'

setattr(sql_aggregates, 'SumWithDefault', SQLSumWithDefault)

由于查找django.db.models.sql.aggregatesSQL聚合类的方式,你需要对新聚合进行monkeypatch,这看起来相当丑陋,但是我们在这里完成的所有工作都添加了一个新的聚合,它包含子类Sum,硬编码调用COALESCE函数并添加占位符对于默认值,您必须提供该关键字参数(至少在此基本示例实现中).

这应该让你做到以下几点:

pictures = gallery.picture_set.annotate(score=SumWithDefault('picturevote__value', default=0).order_by('-score')

推荐阅读
重庆制造漫画社
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有