(self, qs=None)
return new_qs
Join one queryset together with another using a temporary table. If
        no queryset is used, it will use the current queryset and join that
        to itself.

        `Join` either uses the current queryset and effectively does a self-join to
        create a new limited queryset OR it uses a querset given by the user.

        The model of a given queryset needs to contain a valid foreign key to
        the current queryset to perform a join. A new queryset is then created.
Join one queryset together with another using a temporary table. If
        no queryset is used, it will use the current queryset and join that
        to itself.
Join one queryset together with another using a temporary table . If no queryset is used it will use the current queryset and join that to itself .
def join(self, qs=None):
        '''
        Join one queryset together with another using a temporary table. If
        no queryset is used, it will use the current queryset and join that
        to itself.

        `Join` either uses the current queryset and effectively does a self-join to
        create a new limited queryset OR it uses a querset given by the user.

        The model of a given queryset needs to contain a valid foreign key to
        the current queryset to perform a join. A new queryset is then created.
        '''
        to_field = 'id'

        if qs:
            fk = [
                fk for fk in qs.model._meta.fields
                if getattr(fk, 'related_model', None) == self.model
            ]
            fk = fk[0] if fk else None
            model_set = '{}_set'.format(self.model.__name__.lower())
            key = fk or getattr(qs.model, model_set, None)

            if not key:
                raise ValueError('QuerySet is not related to current model')

            try:
                fk_column = key.column
            except AttributeError:
                fk_column = 'id'
                to_field = key.field.column

            qs = qs.only(fk_column)
            # if we give a qs we need to keep the model qs to not lose anything
            new_qs = self
        else:
            fk_column = 'id'
            qs = self.only(fk_column)
            new_qs = self.model.objects.all()

        TABLE_NAME = 'temp_stuff'
        query = self.get_quoted_query(qs.query)
        sql = '''
            DROP TABLE IF EXISTS {table_name};
            DROP INDEX IF EXISTS {table_name}_id;
            CREATE TEMPORARY TABLE {table_name} AS {query};
            CREATE INDEX {table_name}_{fk_column} ON {table_name} ({fk_column});
        '''.format(table_name=TABLE_NAME, fk_column=fk_column, query=str(query))

        with connection.cursor() as cursor:
            cursor.execute(sql)

        class TempModel(models.Model):
            temp_key = models.ForeignKey(
                self.model,
                on_delete=models.DO_NOTHING,
                db_column=fk_column,
                to_field=to_field
            )

            class Meta:
                managed = False
                db_table = TABLE_NAME

        conn = Join(
            table_name=TempModel._meta.db_table,
            parent_alias=new_qs.query.get_initial_alias(),
            table_alias=None,
            join_type='INNER JOIN',
            join_field=self.model.tempmodel_set.rel,
            nullable=False
        )
        new_qs.query.join(conn, reuse=None)
        return new_qs
def join ( self , qs = None ) : to_field = 'id' if qs : fk = [ fk for fk in qs . model . _meta . fields if getattr ( fk , 'related_model' , None ) == self . model ] fk = fk [ 0 ] if fk else None model_set = '{}_set' . format ( self . model . __name__ . lower ( ) ) key = fk or getattr ( qs . model , model_set , None ) if not key : raise ValueError ( 'QuerySet is not related to current model' ) try : fk_column = key . column except AttributeError : fk_column = 'id' to_field = key . field . column qs = qs . only ( fk_column ) # if we give a qs we need to keep the model qs to not lose anything new_qs = self else : fk_column = 'id' qs = self . only ( fk_column ) new_qs = self . model . objects . all ( ) TABLE_NAME = 'temp_stuff' query = self . get_quoted_query ( qs . query ) sql = '''
            DROP TABLE IF EXISTS {table_name};
            DROP INDEX IF EXISTS {table_name}_id;
            CREATE TEMPORARY TABLE {table_name} AS {query};
            CREATE INDEX {table_name}_{fk_column} ON {table_name} ({fk_column});
        ''' . format ( table_name = TABLE_NAME , fk_column = fk_column , query = str ( query ) ) with connection . cursor ( ) as cursor : cursor . execute ( sql ) class TempModel ( models . Model ) : temp_key = models . ForeignKey ( self . model , on_delete = models . DO_NOTHING , db_column = fk_column , to_field = to_field ) class Meta : managed = False db_table = TABLE_NAME conn = Join ( table_name = TempModel . _meta . db_table , parent_alias = new_qs . query . get_initial_alias ( ) , table_alias = None , join_type = 'INNER JOIN' , join_field = self . model . tempmodel_set . rel , nullable = False ) new_qs . query . join ( conn , reuse = None ) return new_qs