Hi all,

We wrote some custom logic that extended the `Query` class. It worked fine 
in 3.2 but not for 4.1, and it started producing invalid SQL. We filed a 
ticket (https://code.djangoproject.com/ticket/35836) but haven't made any 
progress since `Query` is an undocumented API.

Our use case is an automatic site filter - objects belonging to different 
customer sites are automatically filtered to the current site, so each 
queryset doesn't have to be explicitly filtered. We did this at the Query 
level rather than filtering the default manager's `get_queryset`. This has 
the useful effect that our DRF views can define a queryset attribute on 
their class definition (where there isn't a 'current' site) and the query 
will be filtered when it is actually executed (in a request context on a 
particular site)

How should we change our usage of `Query` to fix the bug? Below is the 
contents of the ticket, including a reproduction.

Thanks,
Ben Pearman

___

We have observed a bug in the ORM where invalid SQL can be produced. 

A reproduction can be seen here:
​https://github.com/benpearman/django-orm-bug 
<https://github.com/benpearman/django-orm-bug>
And specifically:
​https://github.com/benpearman/django-orm-bug/blob/master/demo/models.py 
<https://github.com/benpearman/django-orm-bug/blob/master/demo/models.py>

It is caused with the following steps:

   1. Subclassing `django.db.models.sql.Query` and using it in a Queryset 
   mixin 
   2. Creating a queryset with an `exclude()` expression which includes a 
   subquery. EG `Classroom.objects.exclude(student_set__id=student_A.id)` 
   3. Then before calling `super().get_compiler` from our subclassed Query: 
      - Clone the query 
      - Adding a simple expression via `cloned_query.add_q` eg 
      `cloned_query.add_q(Q(school_id=1))` 
      - Passing the cloned query into `super().get_compiler` 
   4. Then evaluate the queryset, which produces invalid SQL and raises 
   `django.db.utils.OperationalError` 

Note the issue happens when `get_compiler` is invoked for the subquery, not 
on the main query itself.

This was working for us in Django 3.2, but not for Django 4.1

git bisect shows the breakage was introduced by this commit:
​
https://github.com/django/django/commit/14c8504a37afad96ab93cf82f47b13bcc4d00621
 
<https://github.com/django/django/commit/14c8504a37afad96ab93cf82f47b13bcc4d00621>

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/af1c619d-eaed-4ad8-896f-849d86f9a674n%40googlegroups.com.

Reply via email to