# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. from django.contrib.gis.db import models from django.db.models.sql.constants import QUERY_TERMS from django.db.backends.postgresql_psycopg2.base import DatabaseWrapper from django.db.backends.postgresql_psycopg2.operations import ( DatabaseOperations) QUERY_TERMS.add('unaccent') DatabaseWrapper.operators['unaccent'] = '=~@ %s' def my_lookup_cast(self, lookup_type): """ Adding 'unaccent' to the standard lookup_cast """ lookup = '%s' # Cast text lookups to text to allow things like filter(x__contains=4) if lookup_type in ('iexact', 'contains', 'icontains', 'unaccent', 'startswith', 'istartswith', 'endswith', 'iendswith'): lookup = "%s::text" # Use UPPER(x) for case-insensitive lookups; it's faster.
lhs_sql = 'UPPER(%s)' % lhs_sql return (lhs_sql, params) def get_rhs_op(self, connection, rhs): return connection.operators['icontains'] % rhs Field.register_lookup(Like) Field.register_lookup(ILike) else: from django.db import connection from django.db.models.fields import Field, subclassing from django.db.models.sql.constants import QUERY_TERMS if isinstance(QUERY_TERMS, set): QUERY_TERMS.add('like') QUERY_TERMS.add('ilike') else: QUERY_TERMS['like'] = None QUERY_TERMS['ilike'] = None connection.operators['like'] = connection.operators['contains'] connection.operators['ilike'] = connection.operators['icontains'] NEW_LOOKUP_TYPE = ('like', 'ilike') def get_prep_lookup(self, lookup_type, value): try: return self.get_prep_lookup_origin(lookup_type, value) except TypeError as e: if lookup_type in NEW_LOOKUP_TYPE: return value
if backend_allowed and 'Lookup' in locals(): # Use Django 1.7 API for registering a new lookup class Similar(Lookup): lookup_name = 'similar' def as_sql(self, qn, connection): lhs, lhs_params = self.process_lhs(qn, connection) rhs, rhs_params = self.process_rhs(qn, connection) params = lhs_params + rhs_params return '%s %%%% %s' % (lhs, rhs), params Field.register_lookup(Similar) elif backend_allowed: # Old pre-Django 1.7 manual injection of lookup if isinstance(QUERY_TERMS, set): QUERY_TERMS.add('similar') else: QUERY_TERMS['similar'] = None if backend_allowed == 'postgis': if isinstance(ALL_TERMS, set): ALL_TERMS.add('similar') else: ALL_TERMS['similar'] = None connection.operators['similar'] = "%%%% %s" NEW_LOOKUP_TYPE = ('similar', ) monkey_get_db_prep_lookup(Field) if hasattr(Field, 'get_prep_lookup'):
def get_rhs_op(self, connection, rhs): return connection.operators['icontains'] % rhs Field.register_lookup(Like) Field.register_lookup(ILike) else: from django.db import backend from django.db import connection from django.db.models.fields import Field, subclassing from django.db.models.sql.constants import QUERY_TERMS if isinstance(QUERY_TERMS, set): QUERY_TERMS.add('like') QUERY_TERMS.add('ilike') else: QUERY_TERMS['like'] = None QUERY_TERMS['ilike'] = None connection.operators['like'] = connection.operators['contains'] connection.operators['ilike'] = connection.operators['icontains'] NEW_LOOKUP_TYPE = ('like', 'ilike') def get_prep_lookup(self, lookup_type, value): try: return self.get_prep_lookup_origin(lookup_type, value) except TypeError as e: if lookup_type in NEW_LOOKUP_TYPE: return value
# along with this software. If not, see <http://www.gnu.org/licenses/>. import django import datetime from django.conf import settings from django.contrib.auth.models import User from django.core.exceptions import FieldError from django.core.management import call_command from django.core.urlresolvers import reverse from django.db.models.sql.constants import QUERY_TERMS from django.test import TestCase if isinstance(QUERY_TERMS, set): QUERY_TERMS.add('error') else: QUERY_TERMS['error'] = None class DjangoLikeTestCase(TestCase): fixtures = ['app_data.json'] def test_like(self): users_like = User.objects.filter(username__like="u%r%") users_regex = User.objects.filter(username__regex="^u.*r.$") self.assertEqual(list(users_like), list(users_regex)) self.assertEqual(users_like.count(), 4) def test_ilike(self):
# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. from django.contrib.gis.db import models from django.db.models.sql.constants import QUERY_TERMS from django.db.backends.postgresql_psycopg2.base import DatabaseWrapper from django.db.backends.postgresql_psycopg2.operations import ( DatabaseOperations) QUERY_TERMS.add('unaccent') DatabaseWrapper.operators['unaccent'] = '=~@ %s' def my_lookup_cast(self, lookup_type): """ Adding 'unaccent' to the standard lookup_cast """ lookup = '%s' # Cast text lookups to text to allow things like filter(x__contains=4) if lookup_type in ('iexact', 'contains', 'icontains', 'unaccent', 'startswith', 'istartswith', 'endswith', 'iendswith'): lookup = "%s::text" # Use UPPER(x) for case-insensitive lookups; it's faster.
# You should have received a copy of the GNU Lesser General Public License # along with this software. If not, see <http://www.gnu.org/licenses/>. import django import datetime from django.conf import settings from django.contrib.auth.models import User from django.core.exceptions import FieldError from django.core.management import call_command from django.core.urlresolvers import reverse from django.db.models.sql.constants import QUERY_TERMS from django.test import TestCase if isinstance(QUERY_TERMS, set): QUERY_TERMS.add('error') else: QUERY_TERMS['error'] = None class DjangoLikeTestCase(TestCase): fixtures = ['app_data.json'] def test_like(self): users_like = User.objects.filter(username__like="u%r%") users_regex = User.objects.filter(username__regex="^u.*r.$") self.assertEqual(list(users_like), list(users_regex)) self.assertEqual(users_like.count(), 4) def test_ilike(self):
return value_returned def monkey_get_db_prep_lookup(cls): cls.get_db_prep_lookup_origin = cls.get_db_prep_lookup cls.get_db_prep_lookup = get_db_prep_lookup if hasattr(subclassing, "call_with_connection_and_prepared"): # Dj > 1.1 setattr(cls, "get_db_prep_lookup", subclassing.call_with_connection_and_prepared(cls.get_db_prep_lookup)) for new_cls in cls.__subclasses__(): monkey_get_db_prep_lookup(new_cls) if backend_allowed: if isinstance(QUERY_TERMS, set): QUERY_TERMS.add("similar") else: QUERY_TERMS["similar"] = None if backend_allowed == "postgis": if isinstance(ALL_TERMS, set): ALL_TERMS.add("similar") else: ALL_TERMS["similar"] = None connection.operators["similar"] = "%%%% %s" NEW_LOOKUP_TYPE = ("similar",) monkey_get_db_prep_lookup(Field) if hasattr(Field, "get_prep_lookup"):