Skip to content

Instantly share code, notes, and snippets.

@Apkawa
Last active June 8, 2021 16:42
Show Gist options
  • Save Apkawa/e30909696ec614d8fc65 to your computer and use it in GitHub Desktop.
Save Apkawa/e30909696ec614d8fc65 to your computer and use it in GitHub Desktop.
Django patch for join with extra
# -*- coding: utf-8 -*-
from .queryset import ExtraJoinQuerySet
class ModelQuerySet(ExtraJoinQuerySet):
def attach_useful_vote(self, user=None):
return self.extra(select={"field": "joined_table.field"},
join=[
"""
JOIN (SELECT rel_id, field FROM subselect_table) AS joined_table ON table.id = joined_table.rel_id
"""
],
)
# -*- coding: utf-8 -*-
import new
from functools import update_wrapper
from django.db.models.query import QuerySet
from django.db.models.sql.query import Query
def replace_method(method, func):
instance = method.im_self
method_name = method.__name__
orig_method = method
func.super = orig_method
update_wrapper(func, method)
setattr(instance, method_name, new.instancemethod(func, instance, instance.__class__))
def SQLCompiler__get_from_clause(self):
from_, f_params = SQLCompiler__get_from_clause.super()
if getattr(self.query, "extra_join", None):
from_.extend(self.query.extra_join)
return from_, f_params
class ExtraJoinQuery(Query):
extra_join = None
def clone(self, **kwargs):
q = super(ExtraJoinQuery, self).clone(**kwargs)
q.extra_join = self.extra_join
return q
def get_compiler(self, using=None, connection=None):
compiler = super(ExtraJoinQuery, self).get_compiler(using=using, connection=connection)
replace_method(compiler.get_from_clause, SQLCompiler__get_from_clause)
return compiler
class ExtraJoinQuerySet(QuerySet):
def __init__(self, model=None, query=None, using=None):
super(ExtraJoinQuerySet, self).__init__(model, query, using)
self.query = query or ExtraJoinQuery(self.model)
def extra(self, **kwargs):
sql_join = kwargs.pop("join", [])
extra_join = getattr(self.query, "extra_join", None) or []
extra_join.extend(sql_join)
setattr(self.query, "extra_join", extra_join)
return super(ExtraJoinQuerySet, self).extra(**kwargs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment