From 198ccc028a9d24e7879db583f8a263a061255742 Mon Sep 17 00:00:00 2001 From: Greg Turner Date: Fri, 6 Aug 2010 20:29:09 +1000 Subject: [PATCH 1/5] made list queries work with regexes (e.g. istartswith) --- mongoengine/fields.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mongoengine/fields.py b/mongoengine/fields.py index 127f029f..73bc7562 100644 --- a/mongoengine/fields.py +++ b/mongoengine/fields.py @@ -319,8 +319,8 @@ class ListField(BaseField): def prepare_query_value(self, op, value): if op in ('set', 'unset'): - return [self.field.to_mongo(v) for v in value] - return self.field.to_mongo(value) + return [self.field.prepare_query_value(op, v) for v in value] + return self.field.prepare_query_value(op, value) def lookup_member(self, member_name): return self.field.lookup_member(member_name) From 809fe44b43decc6f271d3eedd1f637db4149f24c Mon Sep 17 00:00:00 2001 From: Greg Turner Date: Thu, 12 Aug 2010 15:14:20 +1000 Subject: [PATCH 2/5] Added a __raw__ parameter for passing query dictionaries directly to pymongo --- mongoengine/queryset.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mongoengine/queryset.py b/mongoengine/queryset.py index 069ab113..b2460217 100644 --- a/mongoengine/queryset.py +++ b/mongoengine/queryset.py @@ -318,6 +318,11 @@ class QuerySet(object): mongo_query = {} for key, value in query.items(): + + if key == "__raw__": + mongo_query.update(value) + return mongo_query + parts = key.split('__') # Check for an operator and transform to mongo-style if there is op = None From 6373e20696533630979327ed0183ea2cbbc6cc48 Mon Sep 17 00:00:00 2001 From: Greg Turner Date: Fri, 13 Aug 2010 22:28:26 +1000 Subject: [PATCH 3/5] Better error reporting on a validation error for a list. --- mongoengine/fields.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mongoengine/fields.py b/mongoengine/fields.py index 73bc7562..866dc7e3 100644 --- a/mongoengine/fields.py +++ b/mongoengine/fields.py @@ -315,7 +315,7 @@ class ListField(BaseField): try: [self.field.validate(item) for item in value] except Exception, err: - raise ValidationError('Invalid ListField item (%s)' % str(err)) + raise ValidationError('Invalid ListField item (%s)' % str(item)) def prepare_query_value(self, op, value): if op in ('set', 'unset'): From d274576b4739d77803cc4adfda5e069be865d909 Mon Sep 17 00:00:00 2001 From: Greg Turner Date: Fri, 13 Aug 2010 22:30:36 +1000 Subject: [PATCH 4/5] Fixed premature return for query gen --- mongoengine/queryset.py | 57 ++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/mongoengine/queryset.py b/mongoengine/queryset.py index b2460217..3f9b7c5c 100644 --- a/mongoengine/queryset.py +++ b/mongoengine/queryset.py @@ -321,40 +321,39 @@ class QuerySet(object): if key == "__raw__": mongo_query.update(value) - return mongo_query + else: + parts = key.split('__') + # Check for an operator and transform to mongo-style if there is + op = None + if parts[-1] in operators + match_operators: + op = parts.pop() - parts = key.split('__') - # Check for an operator and transform to mongo-style if there is - op = None - if parts[-1] in operators + match_operators: - op = parts.pop() + if _doc_cls: + # Switch field names to proper names [set in Field(name='foo')] + fields = QuerySet._lookup_field(_doc_cls, parts) + parts = [field.db_field for field in fields] - if _doc_cls: - # Switch field names to proper names [set in Field(name='foo')] - fields = QuerySet._lookup_field(_doc_cls, parts) - parts = [field.db_field for field in fields] + # Convert value to proper value + field = fields[-1] + singular_ops = [None, 'ne', 'gt', 'gte', 'lt', 'lte'] + singular_ops += match_operators + if op in singular_ops: + value = field.prepare_query_value(op, value) + elif op in ('in', 'nin', 'all'): + # 'in', 'nin' and 'all' require a list of values + value = [field.prepare_query_value(op, v) for v in value] - # Convert value to proper value - field = fields[-1] - singular_ops = [None, 'ne', 'gt', 'gte', 'lt', 'lte'] - singular_ops += match_operators - if op in singular_ops: - value = field.prepare_query_value(op, value) - elif op in ('in', 'nin', 'all'): - # 'in', 'nin' and 'all' require a list of values - value = [field.prepare_query_value(op, v) for v in value] + if field.__class__.__name__ == 'GenericReferenceField': + parts.append('_ref') - if field.__class__.__name__ == 'GenericReferenceField': - parts.append('_ref') + if op and op not in match_operators: + value = {'$' + op: value} - if op and op not in match_operators: - value = {'$' + op: value} - - key = '.'.join(parts) - if op is None or key not in mongo_query: - mongo_query[key] = value - elif key in mongo_query and isinstance(mongo_query[key], dict): - mongo_query[key].update(value) + key = '.'.join(parts) + if op is None or key not in mongo_query: + mongo_query[key] = value + elif key in mongo_query and isinstance(mongo_query[key], dict): + mongo_query[key].update(value) return mongo_query From b7e84031e310561469b99d62c99dd354e4fa6fe5 Mon Sep 17 00:00:00 2001 From: Greg Turner Date: Thu, 16 Sep 2010 14:37:18 +1000 Subject: [PATCH 5/5] Escape strings for regex query. --- mongoengine/fields.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mongoengine/fields.py b/mongoengine/fields.py index 866dc7e3..79045898 100644 --- a/mongoengine/fields.py +++ b/mongoengine/fields.py @@ -64,7 +64,7 @@ class StringField(BaseField): regex = r'%s$' elif op == 'exact': regex = r'^%s$' - value = re.compile(regex % value, flags) + value = re.compile(regex % re.escape(value), flags) return value