【问题标题】:How to convert NoneType value from aggregate to float in Python?如何在 Python 中将 NoneType 值从聚合转换为浮点数?
【发布时间】:2017-09-12 16:55:05
【问题描述】:

我有一个 Django models.py 文件,其类定义如下:

class Cotizacion(models.Model):
    # Fields
    nombre = models.CharField(max_length=100)
    slug = extension_fields.AutoSlugField(populate_from='nombre', blank=True)
    fecha_vence = models.DateField(default=now)
    _subtotal = models.DecimalField(max_digits=10,
                                    decimal_places=2,
                                    null=True,
                                    blank=True,
                                    db_column='subtotal',
                                    default=0)
    _total = models.DecimalField(max_digits=10,
                                 decimal_places=2,
                                 null=True,
                                 blank=True,
                                 db_column='total',
                                 default=0)
    _utilidad = models.DecimalField(max_digits=8,
                                    decimal_places=6,
                                    null=True,
                                    blank=True,
                                    db_column='utilidad',
                                    default=0)
    # utilidad = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
    # total = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
    creado = models.DateTimeField(auto_now_add=True, editable=False)
    actualizado = models.DateTimeField(auto_now=True, editable=False)

    # Relationship Fields
    itinerario = models.ForeignKey(Itinerario, on_delete=CASCADE, verbose_name='itinerario')
    nivel_de_precio = models.ForeignKey(NivelDePrecio,
                                        verbose_name='nivel de precio',
                                        on_delete=models.PROTECT, null=True)

    class Meta:
        ordering = ('-id',)
        verbose_name = _('Cotización')
        verbose_name_plural = _('Cotizaciones')

    def __str__(self):
        return self.nombre

    def __unicode__(self):
        return u'%s' % self.nombre

    @property
    def subtotal(self):
        agregado = self.lineas.aggregate(subtotal=Sum('monto'))
        return agregado['subtotal']

    @subtotal.setter
    def subtotal(self, value):
        self._subtotal = value

    @property
    def total(self):
        agregado = self.lineas.aggregate(total=Sum('total'))
        return format(math.ceil(agregado['total'] / redondeoLps) * redondeoLps, '.2f')
        # return math.ceil(agregado['total'] / redondeoLps) * redondeoLps

    @total.setter
    def total(self, value):
        self._total = value

    @property
    def utilidad(self):
        agregado1 = self.lineas.aggregate(costo=Sum('monto'))
        agregado2 = self.lineas.aggregate(precio=Sum('total'))
        precio = agregado2['precio']
        precioRnd = math.ceil(precio / redondeoLps) * redondeoLps
        if agregado2['precio'] == 0:
            return 0
        else:
            ganancia = round((precioRnd - agregado1['costo']) / precioRnd, 4)
            return ganancia

    @utilidad.setter
    def utilidad(self, value):
        self._utilidad = value

    def get_absolute_url(self):
        return reverse('transporte_cotizacion_detail', args=(self.slug,))

    def get_update_url(self):
        return reverse('transporte_cotizacion_update', args=(self.slug,))

_subtotal_total_utilidad 字段中使用的聚合值来自相关类 (CotizacionDetalle)这是这个班级的一个孩子,在 Master --> Detail 关系中,是 Cotizacion Header 表和 CotizacionDetalle Lines 表.

从我的前端运行时,我没有收到任何错误,并且会根据需要显示值,如下图所示:

note the 'Precio' value

...但是在运行 Django 管理界面时,我收到以下错误消息:

/admin/transporte/cotizacion/ 处的类型错误

/ 不支持的操作数类型:“NoneType”和“int”

请求方法:GET 请求网址:http://demo.mistenants.com:8000/admin/transporte/cotizacion/ Django 版本:1.9.7 异常类型:TypeError 异常值:

unsupported operand type(s) for /: 'NoneType' and 'int'

异常位置:

C:\Users\adalb\PycharmProjects\tenant\transporte\models.py in utilidad, line 330 

第 330 行是这个:

precioRnd = math.ceil(precio / redondeoLps) * redondeoLps

redondeoLps 是一个值为 50 的 int 类型变量(来自外部参数 API)

奇怪的是,我只有在通过 Django 管理接口访问时才会收到错误消息。 Django 管理模板对数据类型有更严格的评估吗?如何使用聚合函数中的变量执行操作?

【问题讨论】:

标签: python django aggregate-functions type-conversion


【解决方案1】:

你可以的

from django.db.models.functions import Coalesce
self.lineas.aggregate(precio=Coalesce(Sum('total'), 0))

precioRnd = math.ceil((precio or 0) / (redondeoLps or 0)) * redondeoLps

【讨论】:

  • 谢谢,这就是解决方案。
  • 虽然第一个选项解决了问题,但第二个只是将结果替换为0
猜你喜欢
  • 2015-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-21
  • 2020-07-01
  • 2016-01-12
  • 2013-07-01
  • 1970-01-01
相关资源
最近更新 更多