Ticket #6422: query.py.patch

File query.py.patch, 3.9 KB (added by Manfred Wassmann <manolo@…>, 7 years ago)

Patch for django/db/models/query.py

  • query.py

    old new  
    186186        extra_select = self._select.items()
    187187
    188188        cursor = connection.cursor()
    189         cursor.execute("SELECT " + (self._distinct and "DISTINCT " or "") + ",".join(select) + sql, params)
    190 
     189        select, sql, params = self._get_sql_clause()
     190        if self._distinct == False:
     191            distinct = ""
     192        elif self._distinct == True:
     193            distinct = "DISTINCT "
     194        else:
     195            # CHECKME: probably need some qouting around the %s (or use %r ???)
     196            distinct = "DISTINCT ON (%s) " % (
     197                # CHECKME: the type check would not be necessary if the
     198                # distinct method would ensure to store a tuple in
     199                # self._distinct in any case.
     200                type(self._distinct) == type('') and self._distinct
     201                or ','.join(self._distinct))
     202        cursor.execute("SELECT " + distinct + ",".join(select) + sql, params)
    191203        fill_cache = self._select_related
    192204        fields = self.model._meta.fields
    193205        index_end = len(fields)
     
    236248
    237249        cursor = connection.cursor()
    238250        if self._distinct:
     251            # CHECKME: may have to change this for DISTINCT ON queries, i.e.
     252            # when self._distinct is not 'True' but a string or tuple
    239253            id_col = "%s.%s" % (connection.ops.quote_name(self.model._meta.db_table),
    240254                    connection.ops.quote_name(self.model._meta.pk.column))
    241255            cursor.execute("SELECT COUNT(DISTINCT(%s))" % id_col + sql, params)
     
    421435                "Cannot reorder a query once a slice has been taken."
    422436        return self._clone(_order_by=field_names)
    423437
    424     def distinct(self, true_or_false=True):
     438    def distinct(self, true_or_false=True, *fields):
    425439        "Returns a new QuerySet instance with '_distinct' modified."
    426         return self._clone(_distinct=true_or_false)
     440        if fields:
     441            # CHECKME: if fields is a one-tuple a simple string will be stored
     442            # in self._distinct in the cloned object. This leads to more
     443            # complex precessing when the value is used so it would be
     444            # beneficial to make sure to always store a tuple here.
     445            return self._clone(_distinct=fields)
     446        else:
     447            return self._clone(_distinct=true_or_false)
    427448
    428449    def extra(self, select=None, where=None, params=None, tables=None):
    429450        assert self._limit is None and self._offset is None, \
     
    462483        assert self._limit is None and self._offset is None \
    463484            and other._limit is None and other._offset is None, \
    464485            "Cannot combine queries once a slice has been taken."
     486        # CHECKME: for DISTINCT ON queries this will always return false
     487        # unless both field sets are identical. I don't know if this is
     488        # correct, if so the error message may have to be adapted.
    465489        assert self._distinct == other._distinct, \
    466490            "Cannot combine a unique query with a non-unique query"
    467491        #  use 'other's order by
     
    617641            field_names.extend([f[0] for f in extra_select])
    618642
    619643        cursor = connection.cursor()
    620         cursor.execute("SELECT " + (self._distinct and "DISTINCT " or "") + ",".join(select) + sql, params)
     644        if self._distinct == False:
     645            distinct = ""
     646        elif self._distinct == True:
     647            distinct = "DISTINCT "
     648        else:
     649            # CHECKME: see above (same as in the QuerySet class)
     650            distinct = "DISTINCT ON (%s) " % (
     651                type(self._distinct) == type('') and self._distinct
     652                or ','.join(self._distinct))
     653        cursor.execute("SELECT " + distinct + ",".join(select) + sql, params)
    621654
    622655        has_resolve_columns = hasattr(self, 'resolve_columns')
    623656        while 1:
Back to Top