Opened 8 years ago
Last modified 7 years ago
#27332 closed New feature
Specifying additional JOIN arguments — at Version 1
Reported by: | MikiSoft | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Simon Charette, django@…, ticosax@…, josh.smeaton@… | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
For example, this raw SQL:
SELECT event.* FROM event INNER JOIN business ON (event.business_id = business.id AND business.manager_id = 1) LEFT JOIN 'like' ON (event.id = object_id AND content_type_pk = 17 AND person_id = 1) ORDER BY COALESCE('like'.date, event.'when') DESC;
Can't be translated to the equivalent Django ORM expression even if using extra()
command, because there isn't anywhere a possibility to set additional arguments on JOIN
clauses. And when I'm using filter(Q(argument) | ...)
it happens to always push all arguments to WHERE
clause, which just causes a performance hit. I wish there was some parameter which would determine the destination of the argument, whether it has to go to the (last) JOIN
clause, or to be put in WHERE
(which goes by default). Also, I'm not able to comprehend how to perform correctly LEFT JOIN
so in the end I have made some jumbled up expression which is completely inefficient (as it executes two queries, but it's the only way to do the same from above and get QuerySet
in return):
from django.db.models import Q from django.db.models.functions import Coalesce Event.objects.filter(Q(pk__in=Like.objects.filter(person__pk=1, content_type__pk=17).prefetch_related('content_object').values_list('object_id', flat=True)) | Q(business__manager=1)).order_by(Coalesce('likes__date', 'when').desc())
I'm filing this issue because some (or probably many) people like me desperately need output in a form of a QuerySet
because of the pagination and many other things RawQuerySet
doesn't support, so using raw()
isn't definitely an option in my case. Django has left me out of choice.