Django QuerySet按表达式排序[重复]

Posted

技术标签:

【中文标题】Django QuerySet按表达式排序[重复]【英文标题】:Django QuerySet ordering by expression [duplicate] 【发布时间】:2011-02-24 23:55:56 【问题描述】:

可能重复:django - ordering queryset by a calculated field

我怎样才能像 order_by('field1'*'field2') 一样使用 order_by 例如,我有以不同货币列出价格的商品,所以要订购商品 - 我必须进行货币兑换。

class Currency(models.Model):
    code    = models.CharField(max_length=3, primary_key=True) 
    rateToUSD   = models.DecimalField(max_digits=20,decimal_places=10)

class Item(models.Model):
    priceRT     = models.DecimalField(max_digits=15, decimal_places=2, default=0)
    cur     = models.ForeignKey(Currency)

我想要类似的东西:

Item.objects.all().order_by(F('priceRT')*F('cur__rateToUSD'))

但不幸的是它不起作用,我也失败了注释。 如何通过 2 个模型字段的值相乘结果对 QuerySet 进行排序。

【问题讨论】:

【参考方案1】:

使用extra() 方法。特别是 select 参数指定方程,order_by 参数进行排序。

【讨论】:

谢谢!在我的情况下,解决方案看起来像 - Item.objects.filter(q&qDates).extra(select='usdPrice': 'SELECT airsale_item.priceRT/toUSD FROM airsale_currency WHERE airsale_currency.code = airsale_item.cur_id' ).order_by('usdPrice ') 不幸的是,我没有在下一个中使用一个额外的结果。像 I.objects.extra('xx':....).extra('yy': 'xx'*2) django (实际上是 db) throws 'xx' 字段丢失。反正我的问题解决了,谢谢【参考方案2】:

无聊的方式:向您的 Item 类添加一个名为 priceUSD 的额外字段,并使用覆盖的保存方法填充它。意味着您无需为每个查询运行计算 - 只需在每次更新时运行。所以这是否好取决于你是倾向于写更多还是读更多(考虑到你的问题,也许它被读了?)

类似这样的:

class Item(models.Model):
    priceRT     = models.DecimalField(max_digits=15, decimal_places=2, default=0)
    cur     = models.ForeignKey(Currency)
    priceUSD = models.DecimalField(max_digits=15, decimal_places=2, default=0)

    def save(self,*args,**kwargs)
        self.priceUSD = self.priceRT * self.cur.rateToUSD
        super(Model,self).save(*args,**kwargs)

在我的 django 东西中,每当我尝试实现巧妙的计算字段而不将它们存储在数据库中时,我通常会发现它有太多的缺点而无法使用(例如t 查询它们,不能对它们进行排序)。因此,使用自定义保存方法在数据库中存储一个适当的字段是我通常所做的,并且它工作正常。你会想要更多的错误检查和其他东西。

【讨论】:

我认为这种方法的主要优点是您可以为计算字段添加索引,从而使您在大表上的读取查询更快。

以上是关于Django QuerySet按表达式排序[重复]的主要内容,如果未能解决你的问题,请参考以下文章

按模型的属性(不是字段)对 Django QuerySet 进行排序

为啥带有 Q() 表达式的 Django QuerySet 返回重复值?

按日期时间的月/日订购 Django QuerySet?

Django QuerySet OR 语句 [重复]

Django QuerySet 使用给定的排序列表过滤

Django queryset iterator() 没有按预期工作