Trac user jbg has found a regression with the aggregation/annotation
refactor #14030. The crux of the problem comes down to whether annotations
and aggregations should respect constraints on model fields. The specific
example raised is as follows:
Model.objects.aggregate(
sum_price=Sum('price', output_field=DecimalField(max_digits=5,
decimal_places=2)))
Assuming the field "price" is defined as "DecimalField(max_digits=5,
decimal_places=2)", it doesn't matter if output_field is defined or not,
as the implicit F('price') will result in exactly the same behaviour.
Each row in the table will adhere to the max_digits and decimal_places
restriction. It has to, it's part of the column definition. But once you
sum those values together, they are going to overflow. The same problem
would exist if you were to concatenate two CharFields with a max_length=10.
Ticket https://code.djangoproject.com/ticket/23941 has been opened to track
this.
These constraints do not necessarily make sense because we're not
persisting these values anywhere. They are read-only computations, and
should not require bounds. If these values were to be persisted in another
model, then the input fields on that model are required to ensure the
values are valid.
I've implemented https://github.com/django/django/pull/3655/ which
effectively ignores the max_digits and decimal_places arguments in the base
expression class. Subclasses are free to enforce validation if it is
necessary. Further, callers using aren't required to supply bounds checking
in this situation. This is valid (with my patch):
Model.objects.aggregate(
sum_price=Sum('price', output_field=DecimalField()))
And the same goes with CharField() not requiring a max_length argument.
Can anyone see any issues with this approach?
If the above seems sensible, I'll alter the test cases to remove arguments
like decimal_places and max_length, and update the documentation to call
out that these kinds of arguments are not used for annotations.
Thanks,
Josh
--
You received this message because you are subscribed to the Google Groups
"Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-developers/6190d0fd-f1b3-4982-ada5-5520a7ee0e9d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.