#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.

Reply via email to