mirror of
https://github.com/django/django.git
synced 2025-10-31 09:41:08 +00:00
Fixed #1465: added support for regex lookups. Thanks, Tom Tobin.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5555 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
@@ -247,6 +247,8 @@ OPERATOR_MAPPING = {
|
||||
'iexact': 'LIKE %s',
|
||||
'contains': 'LIKE BINARY %s',
|
||||
'icontains': 'LIKE %s',
|
||||
'regex': 'REGEXP BINARY %s',
|
||||
'iregex': 'REGEXP %s',
|
||||
'gt': '> %s',
|
||||
'gte': '>= %s',
|
||||
'lt': '< %s',
|
||||
|
||||
@@ -248,6 +248,8 @@ OPERATOR_MAPPING = {
|
||||
'iexact': 'LIKE %s',
|
||||
'contains': 'LIKE BINARY %s',
|
||||
'icontains': 'LIKE %s',
|
||||
'regex': 'REGEXP BINARY %s',
|
||||
'iregex': 'REGEXP %s',
|
||||
'gt': '> %s',
|
||||
'gte': '>= %s',
|
||||
'lt': '< %s',
|
||||
|
||||
@@ -280,6 +280,8 @@ OPERATOR_MAPPING = {
|
||||
'iexact': 'ILIKE %s',
|
||||
'contains': 'LIKE %s',
|
||||
'icontains': 'ILIKE %s',
|
||||
'regex': '~ %s',
|
||||
'iregex': '~* %s',
|
||||
'gt': '> %s',
|
||||
'gte': '>= %s',
|
||||
'lt': '< %s',
|
||||
|
||||
@@ -225,6 +225,8 @@ OPERATOR_MAPPING = {
|
||||
'iexact': 'ILIKE %s',
|
||||
'contains': 'LIKE %s',
|
||||
'icontains': 'ILIKE %s',
|
||||
'regex': '~ %s',
|
||||
'iregex': '~* %s',
|
||||
'gt': '> %s',
|
||||
'gte': '>= %s',
|
||||
'lt': '< %s',
|
||||
|
||||
@@ -64,9 +64,10 @@ class DatabaseWrapper(local):
|
||||
}
|
||||
kwargs.update(self.options)
|
||||
self.connection = Database.connect(**kwargs)
|
||||
# Register extract and date_trunc functions.
|
||||
# Register extract, date_trunc, and regexp functions.
|
||||
self.connection.create_function("django_extract", 2, _sqlite_extract)
|
||||
self.connection.create_function("django_date_trunc", 2, _sqlite_date_trunc)
|
||||
self.connection.create_function("regexp", 2, _sqlite_regexp)
|
||||
cursor = self.connection.cursor(factory=SQLiteCursorWrapper)
|
||||
cursor.row_factory = utf8rowFactory
|
||||
if settings.DEBUG:
|
||||
@@ -214,6 +215,13 @@ def _sqlite_date_trunc(lookup_type, dt):
|
||||
elif lookup_type == 'day':
|
||||
return "%i-%02i-%02i 00:00:00" % (dt.year, dt.month, dt.day)
|
||||
|
||||
def _sqlite_regexp(re_pattern, re_string):
|
||||
import re
|
||||
try:
|
||||
return bool(re.search(re_pattern, re_string))
|
||||
except:
|
||||
return False
|
||||
|
||||
# SQLite requires LIKE statements to include an ESCAPE clause if the value
|
||||
# being escaped has a percent or underscore in it.
|
||||
# See http://www.sqlite.org/lang_expr.html for an explanation.
|
||||
@@ -222,6 +230,8 @@ OPERATOR_MAPPING = {
|
||||
'iexact': "LIKE %s ESCAPE '\\'",
|
||||
'contains': "LIKE %s ESCAPE '\\'",
|
||||
'icontains': "LIKE %s ESCAPE '\\'",
|
||||
'regex': 'REGEXP %s',
|
||||
'iregex': "REGEXP '(?i)' || %s",
|
||||
'gt': '> %s',
|
||||
'gte': '>= %s',
|
||||
'lt': '< %s',
|
||||
|
||||
@@ -174,7 +174,7 @@ class Field(object):
|
||||
|
||||
def get_db_prep_lookup(self, lookup_type, value):
|
||||
"Returns field's value prepared for database lookup."
|
||||
if lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte', 'month', 'day', 'search'):
|
||||
if lookup_type in ('exact', 'regex', 'iregex', 'gt', 'gte', 'lt', 'lte', 'month', 'day', 'search'):
|
||||
return [value]
|
||||
elif lookup_type in ('range', 'in'):
|
||||
return value
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from django.conf import settings
|
||||
from django.db import backend, connection, transaction
|
||||
from django.db.models.fields import DateField, FieldDoesNotExist
|
||||
from django.db.models import signals, loading
|
||||
@@ -22,6 +23,7 @@ QUERY_TERMS = (
|
||||
'gt', 'gte', 'lt', 'lte', 'in',
|
||||
'startswith', 'istartswith', 'endswith', 'iendswith',
|
||||
'range', 'year', 'month', 'day', 'isnull', 'search',
|
||||
'regex', 'iregex',
|
||||
)
|
||||
|
||||
# Size of each "chunk" for get_iterator calls.
|
||||
@@ -797,6 +799,15 @@ def get_where_clause(lookup_type, table_prefix, field_name, value):
|
||||
return "%s%s IS %sNULL" % (table_prefix, field_name, (not value and 'NOT ' or ''))
|
||||
elif lookup_type == 'search':
|
||||
return backend.get_fulltext_search_sql(table_prefix + field_name)
|
||||
elif lookup_type in ('regex', 'iregex'):
|
||||
if settings.DATABASE_ENGINE == 'oracle':
|
||||
if lookup_type == 'regex':
|
||||
match_option = 'c'
|
||||
else:
|
||||
match_option = 'i'
|
||||
return "REGEXP_LIKE(%s%s, %s, '%s')" % (table_prefix, field_name, cast_sql, match_option)
|
||||
else:
|
||||
raise NotImplementedError
|
||||
raise TypeError, "Got invalid lookup_type: %s" % repr(lookup_type)
|
||||
|
||||
def get_cached_row(klass, row, index_start, max_depth=0, cur_depth=0):
|
||||
|
||||
Reference in New Issue
Block a user