首页 > 解决方案 > 在 Django 2.2.5 中执行 Sum Distinct 时,“NoneType”对象没有属性“lower”。正在开发 Django 2.1.7

问题描述

我的应用程序使用这个相当简单的模型来访问现有表中的数据:

class Table01(models.Model):
    id = models.IntegerField(primary_key=True)
    fecha = models.DateField(blank=True, null=True)
    sucursal = models.IntegerField(blank=True, null=True)
    remito = models.IntegerField(blank=True, null=True)
    codcli = models.IntegerField(blank=True, null=True)
    razon = models.CharField(max_length=25, blank=True, null=True)
    domi = models.CharField(max_length=25, blank=True, null=True)
    turno = models.IntegerField(blank=True, null=True)
    codart = models.TextField(max_length=6, blank=True, null=True)
    canti = models.DecimalField(max_digits=7, decimal_places=2, blank=True, null=True)
    precio = models.DecimalField(max_digits=9, decimal_places=2, blank=True, null=True)
    tot = models.DecimalField(max_digits=7, decimal_places=2, blank=True, null=True)

    class Meta:
        managed = False
        db_table = "TABLE01"
        app_label = "datatables"

该数据库的后端是 SQLite

使用 Django 2.1.7 和此模型,我的应用程序成功执行了以下查询:

sumrem = (Table01.objects.filter(fecha = some_date, turno = some_turno, codcli =some_customer).values("fecha", "turno", "sucursal", "remito", "razon")
.annotate(Sum(F("tot"), distinct=True)))

获得“tot”字段的不同总和,该字段在 Django 2.1.7 上按预期工作

当我升级到 Django 2.2.5 时,出现了这个错误:

Python 3.7.3 (default, Apr  3 2019, 05:39:12) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from .models import Table01
>>> from django.db.models import F, Sum, Count
>>> sumrem = Table01.objects.filter(fecha='2019-05-10', turno=4, codcli=50).values("fecha", "turno", "sucursal", "remito", "razon").annotate(Sum(F("tot"), distinct=True))
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/ricardo/desarrollo/estacion/vr1/lib/python3.7/site-packages/django/db/models/aggregates.py", line 26, in __init__
    raise TypeError("%s does not allow distinct." % self.__class__.__name__)
TypeError: Sum does not allow distinct.

我做了一点研究,发现从 2.2 版开始,根据changelog,“......DISTINCT聚合的处理被添加到Aggregate类中。添加allow_distinct=True为子类的类属性Aggregate允许distinct在初始化时指定关键字参数以确保仅针对每个不同的表达式值调用聚合函数”

所以,我创建了这段小代码,按照Aggregate()的引用示例来实现Sum函数,并设置allow_distinct类属性,以便能够传入distinct=True查询。

#models.py
from django.db.models import Aggregate

class SumD(Aggregate):
    function = "SUM"
    allow_distinct = True


class CountD(Aggregate):
    function = "COUNT"
    allow_distinct = True

当我现在运行查询时,会发生此错误:

>>> from .models import Table01, SumD, CountD
>>> from django.db.models import F, Sum, Count
>>> sumrem = Table01.objects.filter(fecha='2019-05-10', turno=4, codcli=50).values("fecha", "turno", "sucursal", "remito", "razon").annotate(SumD(F("tot"), distinct=True))
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/ricardo/desarrollo/estacion/vr1/lib/python3.7/site-packages/django/db/models/query.py", line 1032, in annotate
    if arg.default_alias in kwargs:
  File "/home/ricardo/desarrollo/estacion/vr1/lib/python3.7/site-packages/django/db/models/aggregates.py", line 64, in default_alias
    return '%s__%s' % (expressions[0].name, self.name.lower())
AttributeError: 'NoneType' object has no attribute 'lower'

现在是我真正迷路的时候:) 非常感谢任何帮助。

真诚的,里卡多。

标签: django

解决方案


找到了!显然,Aggregate()该类需要为结果分配一个名称,与不需要名称的 2.1 版本不同,默认名称为

field__sum

此代码有效:

sumrem = Table01.objects
.values('fecha', 'turno', 'sucursal', 'remito', 'razon')
.filter(fecha=some_date, turno=some_turno, codcli=some_customer)
.annotate(tot=SumD(F('tot'), distinct=True))

我相信这应该更好地记录下来。此致。里卡多。


推荐阅读