Allow updates with match operators (MongoEngine/mongoengine#144)
This commit is contained in:
parent
e6d796832e
commit
e2d826c412
@ -4,7 +4,8 @@ Changelog
|
|||||||
|
|
||||||
Changes in 0.7.X
|
Changes in 0.7.X
|
||||||
================
|
================
|
||||||
- Updated URLField - can have a custom validator (MongoEngine/mongoengine#136)
|
- Allow updates with match operators (MongoEngine/mongoengine#144)
|
||||||
|
- Updated URLField - now can have a override the regex (MongoEngine/mongoengine#136)
|
||||||
- Allow Django AuthenticationBackends to work with Django user (hmarr/mongoengine#573)
|
- Allow Django AuthenticationBackends to work with Django user (hmarr/mongoengine#573)
|
||||||
- Fixed reload issue with ReferenceField where dbref=False (MongoEngine/mongoengine#138)
|
- Fixed reload issue with ReferenceField where dbref=False (MongoEngine/mongoengine#138)
|
||||||
|
|
||||||
|
@ -1395,6 +1395,8 @@ class QuerySet(object):
|
|||||||
"""
|
"""
|
||||||
operators = ['set', 'unset', 'inc', 'dec', 'pop', 'push', 'push_all',
|
operators = ['set', 'unset', 'inc', 'dec', 'pop', 'push', 'push_all',
|
||||||
'pull', 'pull_all', 'add_to_set']
|
'pull', 'pull_all', 'add_to_set']
|
||||||
|
match_operators = ['ne', 'gt', 'gte', 'lt', 'lte', 'in', 'nin', 'mod',
|
||||||
|
'all', 'size', 'exists', 'not']
|
||||||
|
|
||||||
mongo_update = {}
|
mongo_update = {}
|
||||||
for key, value in update.items():
|
for key, value in update.items():
|
||||||
@ -1418,6 +1420,10 @@ class QuerySet(object):
|
|||||||
elif op == 'add_to_set':
|
elif op == 'add_to_set':
|
||||||
op = op.replace('_to_set', 'ToSet')
|
op = op.replace('_to_set', 'ToSet')
|
||||||
|
|
||||||
|
match = None
|
||||||
|
if parts[-1] in match_operators:
|
||||||
|
match = parts.pop()
|
||||||
|
|
||||||
if _doc_cls:
|
if _doc_cls:
|
||||||
# Switch field names to proper names [set in Field(name='foo')]
|
# Switch field names to proper names [set in Field(name='foo')]
|
||||||
fields = QuerySet._lookup_field(_doc_cls, parts)
|
fields = QuerySet._lookup_field(_doc_cls, parts)
|
||||||
@ -1451,16 +1457,22 @@ class QuerySet(object):
|
|||||||
elif field.required or value is not None:
|
elif field.required or value is not None:
|
||||||
value = field.prepare_query_value(op, value)
|
value = field.prepare_query_value(op, value)
|
||||||
|
|
||||||
|
if match:
|
||||||
|
match = '$' + match
|
||||||
|
value = {match: value}
|
||||||
|
|
||||||
key = '.'.join(parts)
|
key = '.'.join(parts)
|
||||||
|
|
||||||
if not op:
|
if not op:
|
||||||
raise InvalidQueryError("Updates must supply an operation eg: set__FIELD=value")
|
raise InvalidQueryError("Updates must supply an operation "
|
||||||
|
"eg: set__FIELD=value")
|
||||||
|
|
||||||
if 'pull' in op and '.' in key:
|
if 'pull' in op and '.' in key:
|
||||||
# Dot operators don't work on pull operations
|
# Dot operators don't work on pull operations
|
||||||
# it uses nested dict syntax
|
# it uses nested dict syntax
|
||||||
if op == 'pullAll':
|
if op == 'pullAll':
|
||||||
raise InvalidQueryError("pullAll operations only support a single field depth")
|
raise InvalidQueryError("pullAll operations only support "
|
||||||
|
"a single field depth")
|
||||||
|
|
||||||
parts.reverse()
|
parts.reverse()
|
||||||
for key in parts:
|
for key in parts:
|
||||||
|
@ -414,6 +414,30 @@ class QuerySetTest(unittest.TestCase):
|
|||||||
self.assertEqual(post.comments[0].by, 'joe')
|
self.assertEqual(post.comments[0].by, 'joe')
|
||||||
self.assertEqual(post.comments[0].votes.score, 4)
|
self.assertEqual(post.comments[0].votes.score, 4)
|
||||||
|
|
||||||
|
def test_updates_can_have_match_operators(self):
|
||||||
|
|
||||||
|
class Post(Document):
|
||||||
|
title = StringField(required=True)
|
||||||
|
tags = ListField(StringField())
|
||||||
|
comments = ListField(EmbeddedDocumentField("Comment"))
|
||||||
|
|
||||||
|
class Comment(EmbeddedDocument):
|
||||||
|
content = StringField()
|
||||||
|
name = StringField(max_length=120)
|
||||||
|
vote = IntField()
|
||||||
|
|
||||||
|
Post.drop_collection()
|
||||||
|
|
||||||
|
comm1 = Comment(content="very funny indeed", name="John S", vote=1)
|
||||||
|
comm2 = Comment(content="kind of funny", name="Mark P", vote=0)
|
||||||
|
|
||||||
|
Post(title='Fun with MongoEngine', tags=['mongodb', 'mongoengine'],
|
||||||
|
comments=[comm1, comm2]).save()
|
||||||
|
|
||||||
|
Post.objects().update_one(pull__comments__vote__lt=1)
|
||||||
|
|
||||||
|
self.assertEqual(1, len(Post.objects.first().comments))
|
||||||
|
|
||||||
def test_mapfield_update(self):
|
def test_mapfield_update(self):
|
||||||
"""Ensure that the MapField can be updated."""
|
"""Ensure that the MapField can be updated."""
|
||||||
class Member(EmbeddedDocument):
|
class Member(EmbeddedDocument):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user