Ticket #5763: #5763-ne_notin-1.4.diff

File #5763-ne_notin-1.4.diff, 10.4 KB (added by German M. Bravo, 12 years ago)

django 1.4 compatible patch

  • django/db/backends/mysql/base.py

    diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py
    index 830808b..b47e4e6 100644
    a b class DatabaseOperations(BaseDatabaseOperations):  
    307307class DatabaseWrapper(BaseDatabaseWrapper):
    308308    vendor = 'mysql'
    309309    operators = {
     310        'ne': '<> %s',
    310311        'exact': '= %s',
    311312        'iexact': 'LIKE %s',
    312313        'contains': 'LIKE BINARY %s',
  • django/db/backends/oracle/base.py

    diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py
    index 105730c..1a712f6 100644
    a b class DatabaseWrapper(BaseDatabaseWrapper):  
    407407    operators = _UninitializedOperatorsDescriptor()
    408408
    409409    _standard_operators = {
     410        'ne': '<> %s',
    410411        'exact': '= %s',
    411412        'iexact': '= UPPER(%s)',
    412413        'contains': "LIKE TRANSLATE(%s USING NCHAR_CS) ESCAPE TRANSLATE('\\' USING NCHAR_CS)",
  • django/db/backends/postgresql_psycopg2/base.py

    diff --git a/django/db/backends/postgresql_psycopg2/base.py b/django/db/backends/postgresql_psycopg2/base.py
    index a77eccf..0919611 100644
    a b class DatabaseFeatures(BaseDatabaseFeatures):  
    9797class DatabaseWrapper(BaseDatabaseWrapper):
    9898    vendor = 'postgresql'
    9999    operators = {
     100        'ne': '<> %s',
    100101        'exact': '= %s',
    101102        'iexact': '= UPPER(%s)',
    102103        'contains': 'LIKE %s',
  • django/db/backends/sqlite3/base.py

    diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py
    index b5d38bb..e6ad1cd 100644
    a b class DatabaseWrapper(BaseDatabaseWrapper):  
    204204    # being escaped has a percent or underscore in it.
    205205    # See http://www.sqlite.org/lang_expr.html for an explanation.
    206206    operators = {
     207        'ne': '<> %s',
    207208        'exact': '= %s',
    208209        'iexact': "LIKE %s ESCAPE '\\'",
    209210        'contains': "LIKE %s ESCAPE '\\'",
  • django/db/models/fields/__init__.py

    diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
    index 04b13aa..851b2ec 100644
    a b class Field(object):  
    306306                'endswith', 'iendswith', 'isnull'
    307307            ):
    308308            return value
    309         elif lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte'):
     309        elif lookup_type in ('exact', 'ne', 'gt', 'gte', 'lt', 'lte'):
    310310            return self.get_prep_value(value)
    311         elif lookup_type in ('range', 'in'):
     311        elif lookup_type in ('range', 'in', 'notin'):
    312312            return [self.get_prep_value(v) for v in value]
    313313        elif lookup_type == 'year':
    314314            try:
    class Field(object):  
    342342        if lookup_type in ('regex', 'iregex', 'month', 'day', 'week_day',
    343343                           'search'):
    344344            return [value]
    345         elif lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte'):
     345        elif lookup_type in ('exact', 'ne', 'gt', 'gte', 'lt', 'lte'):
    346346            return [self.get_db_prep_value(value, connection=connection,
    347347                                           prepared=prepared)]
    348         elif lookup_type in ('range', 'in'):
     348        elif lookup_type in ('range', 'in', 'notin'):
    349349            return [self.get_db_prep_value(v, connection=connection,
    350350                                           prepared=prepared) for v in value]
    351351        elif lookup_type in ('contains', 'icontains'):
  • django/db/models/fields/related.py

    diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
    index ad05c83..8fba124 100644
    a b class RelatedField(object):  
    133133        # get_(next/prev)_by_date work; other lookups are not allowed since that
    134134        # gets messy pretty quick. This is a good candidate for some refactoring
    135135        # in the future.
    136         if lookup_type in ['exact', 'gt', 'lt', 'gte', 'lte']:
     136        if lookup_type in ['exact', 'ne', 'gt', 'lt', 'gte', 'lte']:
    137137            return self._pk_trace(value, 'get_prep_lookup', lookup_type)
    138         if lookup_type in ('range', 'in'):
     138        if lookup_type in ('range', 'in', 'notin'):
    139139            return [self._pk_trace(v, 'get_prep_lookup', lookup_type) for v in value]
    140140        elif lookup_type == 'isnull':
    141141            return []
    class RelatedField(object):  
    161161        # get_(next/prev)_by_date work; other lookups are not allowed since that
    162162        # gets messy pretty quick. This is a good candidate for some refactoring
    163163        # in the future.
    164         if lookup_type in ['exact', 'gt', 'lt', 'gte', 'lte']:
     164        if lookup_type in ['exact', 'ne', 'gt', 'lt', 'gte', 'lte']:
    165165            return [self._pk_trace(value, 'get_db_prep_lookup', lookup_type,
    166166                            connection=connection, prepared=prepared)]
    167         if lookup_type in ('range', 'in'):
     167        if lookup_type in ('range', 'in', 'notin'):
    168168            return [self._pk_trace(v, 'get_db_prep_lookup', lookup_type,
    169169                            connection=connection, prepared=prepared)
    170170                    for v in value]
    class RelatedField(object):  
    205205            else:
    206206                field = field.rel.to._meta.pk
    207207
    208         if lookup_type in ('range', 'in'):
     208        if lookup_type in ('range', 'in', 'notin'):
    209209            v = [v]
    210210        v = getattr(field, prep_func)(lookup_type, v, **kwargs)
    211211        if isinstance(v, list):
  • django/db/models/sql/constants.py

    diff --git a/django/db/models/sql/constants.py b/django/db/models/sql/constants.py
    index 63c704f..0ba218c 100644
    a b import re  
    22
    33# Valid query types (a dictionary is used for speedy lookups).
    44QUERY_TERMS = dict([(x, None) for x in (
    5     'exact', 'iexact', 'contains', 'icontains', 'gt', 'gte', 'lt', 'lte', 'in',
    6     'startswith', 'istartswith', 'endswith', 'iendswith', 'range', 'year',
     5    'exact', 'ne', 'iexact', 'contains', 'icontains', 'gt', 'gte', 'lt', 'lte', 'in',
     6    'notin', 'startswith', 'istartswith', 'endswith', 'iendswith', 'range', 'year',
    77    'month', 'day', 'week_day', 'isnull', 'search', 'regex', 'iregex',
    88    )])
    99
  • django/db/models/sql/query.py

    diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
    index 4891855..f6fc472 100644
    a b class Query(object):  
    10711071        # Interpret '__exact=None' as the sql 'is NULL'; otherwise, reject all
    10721072        # uses of None as a query value.
    10731073        if value is None:
    1074             if lookup_type != 'exact':
     1074            if lookup_type not in ('exact', 'ne'):
    10751075                raise ValueError("Cannot use None as a query value")
     1076            value = lookup_type == 'exact'
    10761077            lookup_type = 'isnull'
    1077             value = True
    10781078        elif callable(value):
    10791079            value = value()
    10801080        elif isinstance(value, ExpressionNode):
    class Query(object):  
    11791179                            entry.negate()
    11801180                            self.where.add(entry, AND)
    11811181                            break
    1182                 if not (lookup_type == 'in'
     1182                if not (lookup_type in ('in', 'notin')
    11831183                            and not hasattr(value, 'as_sql')
    11841184                            and not hasattr(value, '_as_sql')
    11851185                            and not value) and field.null:
    class Query(object):  
    11871187                    # exclude the "foo__in=[]" case from this handling, because
    11881188                    # it's short-circuited in the Where class.
    11891189                    # We also need to handle the case where a subquery is provided
    1190                     self.where.add((Constraint(alias, col, None), 'isnull', False), AND)
     1190                    self.where.add((Constraint(alias, col, None), 'isnull', lookup_type == 'notin'), AND)
    11911191
    11921192        if can_reuse is not None:
    11931193            can_reuse.update(join_list)
  • django/db/models/sql/where.py

    diff --git a/django/db/models/sql/where.py b/django/db/models/sql/where.py
    index 1455ba6..e1aa6c3 100644
    a b class WhereNode(tree.Node):  
    165165        else:
    166166            extra = ''
    167167
    168         if (len(params) == 1 and params[0] == '' and lookup_type == 'exact'
     168        if (len(params) == 1 and params[0] == '' and lookup_type in ('exact', 'ne')
    169169            and connection.features.interprets_empty_strings_as_nulls):
     170            value_annot = lookup_type == 'exact'
    170171            lookup_type = 'isnull'
    171             value_annot = True
    172172
    173173        if lookup_type in connection.operators:
    174174            format = "%s %%s %%s" % (connection.ops.lookup_cast(lookup_type),)
    class WhereNode(tree.Node):  
    176176                              connection.operators[lookup_type] % cast_sql,
    177177                              extra), params)
    178178
    179         if lookup_type == 'in':
     179        if lookup_type in ('in', 'notin'):
    180180            if not value_annot:
    181181                raise EmptyResultSet
     182            if lookup_type == 'in':
     183                op = 'IN'
     184            else:
     185                op = 'NOT IN'
    182186            if extra:
    183                 return ('%s IN %s' % (field_sql, extra), params)
     187                return ('%s %s %s' % (field_sql, op, extra), params)
    184188            max_in_list_size = connection.ops.max_in_list_size()
    185189            if max_in_list_size and len(params) > max_in_list_size:
    186190                # Break up the params list into an OR of manageable chunks.
    class WhereNode(tree.Node):  
    188192                for offset in xrange(0, len(params), max_in_list_size):
    189193                    if offset > 0:
    190194                        in_clause_elements.append(' OR ')
    191                     in_clause_elements.append('%s IN (' % field_sql)
     195                    in_clause_elements.append('%s %s (' % (field_sql, op))
    192196                    group_size = min(len(params) - offset, max_in_list_size)
    193197                    param_group = ', '.join(repeat('%s', group_size))
    194198                    in_clause_elements.append(param_group)
    class WhereNode(tree.Node):  
    196200                in_clause_elements.append(')')
    197201                return ''.join(in_clause_elements), params
    198202            else:
    199                 return ('%s IN (%s)' % (field_sql,
     203                return ('%s %s (%s)' % (field_sql, op,
    200204                                        ', '.join(repeat('%s', len(params)))),
    201205                        params)
    202206        elif lookup_type in ('range', 'year'):
Back to Top