Ticket #1465: trunk-regex_field_lookup.diff

File trunk-regex_field_lookup.diff, 5.0 KB (added by Tom Tobin <korpios@…>, 9 years ago)

patch against r2487 of trunk to implement regular expression field lookups

  • contrib/admin/views/main.py

     
    219219                        break
    220220        lookup_params['order_by'] = ((order_type == 'desc' and '-' or '') + lookup_order_field,)
    221221        if lookup_opts.admin.search_fields and query:
    222             complex_queries = []
    223             for bit in query.split():
     222            # regular expression
     223            if len(query) > 2 and query[0] == '/' and query[-1] == '/':
    224224                or_queries = []
    225225                for field_name in lookup_opts.admin.search_fields:
    226                     or_queries.append(meta.Q(**{'%s__icontains' % field_name: bit}))
    227                 complex_queries.append(reduce(operator.or_, or_queries))
    228             lookup_params['complex'] = reduce(operator.and_, complex_queries)
     226                    or_queries.append(meta.Q(**{'%s__iregex' % field_name: query[1:-1]}))
     227                lookup_params['complex'] = reduce(operator.or_, or_queries)
     228            else:
     229                complex_queries = []
     230                for bit in query.split():
     231                    or_queries = []
     232                    for field_name in lookup_opts.admin.search_fields:
     233                        or_queries.append(meta.Q(**{'%s__icontains' % field_name: bit}))
     234                    complex_queries.append(reduce(operator.or_, or_queries))
     235                lookup_params['complex'] = reduce(operator.and_, complex_queries)
    229236        if opts.one_to_one_field:
    230237            lookup_params.update(opts.one_to_one_field.rel.limit_choices_to)
    231238        self.lookup_params = lookup_params
  • core/db/backends/postgresql.py

     
    172172    'iexact': 'ILIKE %s',
    173173    'contains': 'LIKE %s',
    174174    'icontains': 'ILIKE %s',
     175    'regex': '~ %s',
     176    'iregex': '~* %s',
    175177    'ne': '!= %s',
    176178    'gt': '> %s',
    177179    'gte': '>= %s',
  • core/db/backends/sqlite3.py

     
    3636            # register extract and date_trun functions
    3737            self.connection.create_function("django_extract", 2, _sqlite_extract)
    3838            self.connection.create_function("django_date_trunc", 2, _sqlite_date_trunc)
     39            self.connection.create_function("regexp", 2, _sqlite_regexp)
    3940        cursor = self.connection.cursor(factory=SQLiteCursorWrapper)
    4041        cursor.row_factory = utf8rowFactory
    4142        if DEBUG:
     
    137138def get_indexes(cursor, table_name):
    138139    raise NotImplementedError
    139140
     141def _sqlite_regexp(re_pattern, re_string):
     142    import re
     143    try:
     144        return bool(re.search(re_pattern, re_string, re.I))
     145    except:
     146        return False
     147
    140148# Operators and fields ########################################################
    141149
    142150# SQLite requires LIKE statements to include an ESCAPE clause if the value
     
    147155    'iexact': "LIKE %s ESCAPE '\\'",
    148156    'contains': "LIKE %s ESCAPE '\\'",
    149157    'icontains': "LIKE %s ESCAPE '\\'",
     158    'regex': "REGEXP %s",
     159    'iregex': "REGEXP %s",
    150160    'ne': '!= %s',
    151161    'gt': '> %s',
    152162    'gte': '>= %s',
  • core/db/backends/mysql.py

     
    156156    'iexact': 'LIKE %s',
    157157    'contains': 'LIKE BINARY %s',
    158158    'icontains': 'LIKE %s',
     159    'regex': 'REGEXP %s',
     160    'iregex': 'REGEXP %s',
    159161    'ne': '!= %s',
    160162    'gt': '> %s',
    161163    'gte': '>= %s',
  • core/meta/__init__.py

     
    13491349        return "%s = %%s" % db.get_date_extract_sql(lookup_type, table_prefix + field_name)
    13501350    elif lookup_type == 'isnull':
    13511351        return "%s%s IS %sNULL" % (table_prefix, field_name, (not value and 'NOT ' or ''))
     1352    elif lookup_type in ('regex', 'iregex'):
     1353        raise NotImplementedError
    13521354    raise TypeError, "Got invalid lookup_type: %s" % repr(lookup_type)
    13531355
    13541356def function_get_object(opts, klass, does_not_exist_exception, **kwargs):
  • core/meta/fields.py

     
    175175
    176176    def get_db_prep_lookup(self, lookup_type, value):
    177177        "Returns field's value prepared for database lookup."
    178         if lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte', 'ne', 'year', 'month', 'day'):
     178        if lookup_type in ('exact', 'regex', 'iregex', 'gt', 'gte', 'lt', 'lte', 'ne', 'year', 'month', 'day'):
    179179            return [value]
    180180        elif lookup_type in ('range', 'in'):
    181181            return value
Back to Top