From a2c78c9063658d566cfe3d12c12b2d47c9672222 Mon Sep 17 00:00:00 2001 From: Flavio Amieiro Date: Wed, 26 May 2010 20:24:57 -0300 Subject: [PATCH] Add 'exact' and 'iexact' match operators for QuerySets --- mongoengine/fields.py | 4 +++- mongoengine/queryset.py | 5 +++-- tests/queryset.py | 24 ++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/mongoengine/fields.py b/mongoengine/fields.py index 75008d6f..127f029f 100644 --- a/mongoengine/fields.py +++ b/mongoengine/fields.py @@ -51,7 +51,7 @@ class StringField(BaseField): if not isinstance(op, basestring): return value - if op.lstrip('i') in ('startswith', 'endswith', 'contains'): + if op.lstrip('i') in ('startswith', 'endswith', 'contains', 'exact'): flags = 0 if op.startswith('i'): flags = re.IGNORECASE @@ -62,6 +62,8 @@ class StringField(BaseField): regex = r'^%s' elif op == 'endswith': regex = r'%s$' + elif op == 'exact': + regex = r'^%s$' value = re.compile(regex % value, flags) return value diff --git a/mongoengine/queryset.py b/mongoengine/queryset.py index 72a474d7..57600b10 100644 --- a/mongoengine/queryset.py +++ b/mongoengine/queryset.py @@ -307,8 +307,9 @@ class QuerySet(object): """ operators = ['ne', 'gt', 'gte', 'lt', 'lte', 'in', 'nin', 'mod', 'all', 'size', 'exists', 'near'] - match_operators = ['contains', 'icontains', 'startswith', - 'istartswith', 'endswith', 'iendswith'] + match_operators = ['contains', 'icontains', 'startswith', + 'istartswith', 'endswith', 'iendswith', + 'exact', 'iexact'] mongo_query = {} for key, value in query.items(): diff --git a/tests/queryset.py b/tests/queryset.py index 9daa73ec..e512cd7c 100644 --- a/tests/queryset.py +++ b/tests/queryset.py @@ -265,6 +265,30 @@ class QuerySetTest(unittest.TestCase): obj = self.Person.objects(Q(name__iendswith='rossuM')).first() self.assertEqual(obj, person) + # Test exact + obj = self.Person.objects(name__exact='Guido van Rossum').first() + self.assertEqual(obj, person) + obj = self.Person.objects(name__exact='Guido van rossum').first() + self.assertEqual(obj, None) + obj = self.Person.objects(name__exact='Guido van Rossu').first() + self.assertEqual(obj, None) + obj = self.Person.objects(Q(name__exact='Guido van Rossum')).first() + self.assertEqual(obj, person) + obj = self.Person.objects(Q(name__exact='Guido van rossum')).first() + self.assertEqual(obj, None) + obj = self.Person.objects(Q(name__exact='Guido van Rossu')).first() + self.assertEqual(obj, None) + + # Test iexact + obj = self.Person.objects(name__iexact='gUIDO VAN rOSSUM').first() + self.assertEqual(obj, person) + obj = self.Person.objects(name__iexact='gUIDO VAN rOSSU').first() + self.assertEqual(obj, None) + obj = self.Person.objects(Q(name__iexact='gUIDO VAN rOSSUM')).first() + self.assertEqual(obj, person) + obj = self.Person.objects(Q(name__iexact='gUIDO VAN rOSSU')).first() + self.assertEqual(obj, None) + def test_filter_chaining(self): """Ensure filters can be chained together. """