#34552: Delaying get_from_clause call as much as possible.
-------------------------------------+-------------------------------------
Reporter: Matthew | Owner: nobody
Schinckel |
Type: New | Status: new
feature |
Component: Database | Version: 4.2
layer (models, ORM) |
Severity: Normal | Keywords:
Triage Stage: | Has patch: 1
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
I've got a couple of projects that supplement ORM functionality. One in
particular is [django-shared-property](https://github.com/schinckel
/django-shared-property), which allows a field to be defined on the model,
that will automatically be added as an annotation, and as such can be
filtered/aggregated.
However, it's also "live" in the sense that changes made after loading
from the database to dependencies of the property will be reflected.
For example:
{{{
class Ordering(models.Model):
a = models.IntegerField()
b = models.IntegerField()
class MyModel(models.Model):
ord = models.ForeignKey(Ordering)
@shared_property(models.F('ord__a') / models.F('ord__b'))
def ordering(self):
return self.ord.a / self.ord.b
}}}
In this case, you can filter/order by `ordering`, but also if you changed
`ord.a`, then `ordering` would update accordingly, without having to save
the object and refetch.
Anyway, long story short, this code works amazingly well without any
changes to the Django code, except for one edge case: when a
shared_property refers to another model (which on it's own works), but you
then filter on this shared_property (which again, works) and then do a
`.count()` or `.exists()`.
{{{
MyModel.objects.filter(ordering__gte=10).count()
}}}
It turns out that because of the way the ORM compiler works,
`get_from_clause` is called before any filters are applied. Which normally
works okay, but in this case results in the table not being available.
A solution I came up with was to delay the evaluation of `get_from_clause`
until after the where/having clauses have been processed, allowing them to
flag tables that need to be referenced.
As such, I'd like to propose the change in
https://github.com/django/django/pull/14683, which passes django tests
(and also fixes the problem for me).
--
Ticket URL: <https://code.djangoproject.com/ticket/34552>
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/010701880008b7d7-ef27cd4e-ee2c-4de2-a9ba-2639807d0fcb-000000%40eu-central-1.amazonses.com.