#34564: returning None instead of zero in Count annotation
-------------------------------------+-------------------------------------
Reporter: Amin | Owner: nobody
Aminian |
Type: Bug | Status: new
Component: Database | Version: 4.2
layer (models, ORM) | Keywords: count, orm,
Severity: Normal | annotate
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
I am trying to upgrade the Django's version from 3.2 to 4.2 in my project.
after installation, some of my tests were broken.
The problem:
I am annotating a queryset with Count function, and the count result in
some objects should be zero.
This is my code:
{{{
Order.objects.annotate(count=Count("customer", distinct=True))
}}}
In Django==3.2, if some orders don't have any customers, the count field
would be zero (as I want).
But in Django==4.2, if some orders don't have any customers, the count
field would be None, which breaks my code.
I read the source code for both versions. In version 3.2, we have a method
called `convert_value` in `Count` class in `aggregates` module. The method
is:
{{{
class Count(Aggregate):
...
def convert_value(self, value, expression, connection):
return 0 if value is None else value
}}}
As we can see, this function is responsible to return 0 instead of None.
But this method is deleted in version 4.2, and the conversion is handling
in `convert_value` property in `BaseExpression` class in `expressions`
module:
{{{
class BaseExpression:
...
@cached_property
def convert_value(self):
field = self.output_field
internal_type = field.get_internal_type()
if internal_type == "FloatField":
return (
lambda value, expression, connection: None
if value is None
else float(value)
)
elif internal_type.endswith("IntegerField"):
return (
lambda value, expression, connection: None
if value is None
else int(value)
)
elif internal_type == "DecimalField":
return (
lambda value, expression, connection: None
if value is None
else Decimal(value)
)
return self._convert_value_noop
}}}
In this property we are return a lambda function to be called later, and
when we call this lambda, what ever we pass to it, we would get None as
the result.
Should it be something like returning 0, if the value is None ?
--
Ticket URL: <https://code.djangoproject.com/ticket/34564>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/010701881505ae69-5ae62e9d-1732-4e04-8339-abb96808d524-000000%40eu-central-1.amazonses.com.