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. """