Compare commits
5 Commits
base-docum
...
v0.18.2
Author | SHA1 | Date | |
---|---|---|---|
|
af292b0ec2 | ||
|
1ead7f9b2b | ||
|
5c91877b69 | ||
|
b1002dd4f9 | ||
|
8f57279dc7 |
@@ -102,5 +102,5 @@ deploy:
|
|||||||
on:
|
on:
|
||||||
tags: true
|
tags: true
|
||||||
repo: MongoEngine/mongoengine
|
repo: MongoEngine/mongoengine
|
||||||
condition: ($PYMONGO = 3.x) && ($MONGODB = 3.4)
|
condition: ($PYMONGO = 3.x) && ($MONGODB = 3.4.17)
|
||||||
python: 2.7
|
python: 2.7
|
||||||
|
@@ -6,7 +6,11 @@ Changelog
|
|||||||
Development
|
Development
|
||||||
===========
|
===========
|
||||||
- (Fill this out as you fix issues and develop your features).
|
- (Fill this out as you fix issues and develop your features).
|
||||||
- Add a `BaseDocument.to_dict` method #2101
|
|
||||||
|
Changes in 0.18.2
|
||||||
|
=================
|
||||||
|
- Replace some of the deprecated PyMongo v2.x methods with their v3.x equivalents #2097
|
||||||
|
- Various code clarity and documentation improvements
|
||||||
|
|
||||||
Changes in 0.18.1
|
Changes in 0.18.1
|
||||||
=================
|
=================
|
||||||
|
@@ -23,7 +23,7 @@ __all__ = (list(document.__all__) + list(fields.__all__) +
|
|||||||
list(signals.__all__) + list(errors.__all__))
|
list(signals.__all__) + list(errors.__all__))
|
||||||
|
|
||||||
|
|
||||||
VERSION = (0, 18, 1)
|
VERSION = (0, 18, 2)
|
||||||
|
|
||||||
|
|
||||||
def get_version():
|
def get_version():
|
||||||
|
@@ -309,7 +309,9 @@ class BaseDocument(object):
|
|||||||
return self._data['_text_score']
|
return self._data['_text_score']
|
||||||
|
|
||||||
def to_mongo(self, use_db_field=True, fields=None):
|
def to_mongo(self, use_db_field=True, fields=None):
|
||||||
"""Return as SON data ready for use with MongoDB."""
|
"""
|
||||||
|
Return as SON data ready for use with MongoDB.
|
||||||
|
"""
|
||||||
fields = fields or []
|
fields = fields or []
|
||||||
|
|
||||||
data = SON()
|
data = SON()
|
||||||
@@ -410,35 +412,12 @@ class BaseDocument(object):
|
|||||||
message = 'ValidationError (%s:%s) ' % (self._class_name, pk)
|
message = 'ValidationError (%s:%s) ' % (self._class_name, pk)
|
||||||
raise ValidationError(message, errors=errors)
|
raise ValidationError(message, errors=errors)
|
||||||
|
|
||||||
def to_dict(self):
|
|
||||||
"""Serialize this document into a dict.
|
|
||||||
|
|
||||||
Return field names as they're defined on the document (as opposed to
|
|
||||||
e.g. how they're stored in MongoDB). Return values in their
|
|
||||||
deserialized form (i.e. the same form that you get when you access
|
|
||||||
`doc.some_field_name`). Serialize embedded documents recursively.
|
|
||||||
|
|
||||||
The resultant dict can be consumed easily by other modules which
|
|
||||||
don't need to be aware of MongoEngine-specific object types.
|
|
||||||
|
|
||||||
:return dict: dictionary of field name & value pairs.
|
|
||||||
"""
|
|
||||||
data_dict = {}
|
|
||||||
for field_name in self._fields:
|
|
||||||
value = getattr(self, field_name)
|
|
||||||
if isinstance(value, BaseDocument):
|
|
||||||
data_dict[field_name] = value.to_dict()
|
|
||||||
else:
|
|
||||||
data_dict[field_name] = value
|
|
||||||
return data_dict
|
|
||||||
|
|
||||||
def to_json(self, *args, **kwargs):
|
def to_json(self, *args, **kwargs):
|
||||||
"""Convert this document to JSON.
|
"""Convert this document to JSON.
|
||||||
|
|
||||||
:param use_db_field: Serialize field names as they appear in
|
:param use_db_field: Serialize field names as they appear in
|
||||||
MongoDB (as opposed to attribute names on this document).
|
MongoDB (as opposed to attribute names on this document).
|
||||||
Defaults to True.
|
Defaults to True.
|
||||||
:return str: string representing the jsonified document.
|
|
||||||
"""
|
"""
|
||||||
use_db_field = kwargs.pop('use_db_field', True)
|
use_db_field = kwargs.pop('use_db_field', True)
|
||||||
return json_util.dumps(self.to_mongo(use_db_field), *args, **kwargs)
|
return json_util.dumps(self.to_mongo(use_db_field), *args, **kwargs)
|
||||||
@@ -447,13 +426,12 @@ class BaseDocument(object):
|
|||||||
def from_json(cls, json_data, created=False):
|
def from_json(cls, json_data, created=False):
|
||||||
"""Converts json data to a Document instance
|
"""Converts json data to a Document instance
|
||||||
|
|
||||||
:param str json_data: The json data to load into the Document
|
:param json_data: The json data to load into the Document
|
||||||
:param bool created: If True, the document will be considered as
|
:param created: If True, the document will be considered as a brand new document
|
||||||
a brand new document. If False and an ID is provided, it will
|
If False and an id is provided, it will consider that the data being
|
||||||
consider that the data being loaded corresponds to what's already
|
loaded corresponds to what's already in the database (This has an impact of subsequent call to .save())
|
||||||
in the database (This has an impact of subsequent call to .save())
|
If False and no id is provided, it will consider the data as a new document
|
||||||
If False and no id is provided, it will consider the data as a new
|
(default ``False``)
|
||||||
document (default ``False``)
|
|
||||||
"""
|
"""
|
||||||
return cls._from_son(json_util.loads(json_data), created=created)
|
return cls._from_son(json_util.loads(json_data), created=created)
|
||||||
|
|
||||||
|
@@ -10,6 +10,7 @@ from operator import itemgetter
|
|||||||
from bson import Binary, DBRef, ObjectId, SON
|
from bson import Binary, DBRef, ObjectId, SON
|
||||||
import gridfs
|
import gridfs
|
||||||
import pymongo
|
import pymongo
|
||||||
|
from pymongo import ReturnDocument
|
||||||
import six
|
import six
|
||||||
from six import iteritems
|
from six import iteritems
|
||||||
|
|
||||||
@@ -1964,10 +1965,12 @@ class SequenceField(BaseField):
|
|||||||
sequence_name = self.get_sequence_name()
|
sequence_name = self.get_sequence_name()
|
||||||
sequence_id = '%s.%s' % (sequence_name, self.name)
|
sequence_id = '%s.%s' % (sequence_name, self.name)
|
||||||
collection = get_db(alias=self.db_alias)[self.collection_name]
|
collection = get_db(alias=self.db_alias)[self.collection_name]
|
||||||
counter = collection.find_and_modify(query={'_id': sequence_id},
|
|
||||||
update={'$inc': {'next': 1}},
|
counter = collection.find_one_and_update(
|
||||||
new=True,
|
filter={'_id': sequence_id},
|
||||||
upsert=True)
|
update={'$inc': {'next': 1}},
|
||||||
|
return_document=ReturnDocument.AFTER,
|
||||||
|
upsert=True)
|
||||||
return self.value_decorator(counter['next'])
|
return self.value_decorator(counter['next'])
|
||||||
|
|
||||||
def set_next_value(self, value):
|
def set_next_value(self, value):
|
||||||
@@ -1975,10 +1978,11 @@ class SequenceField(BaseField):
|
|||||||
sequence_name = self.get_sequence_name()
|
sequence_name = self.get_sequence_name()
|
||||||
sequence_id = "%s.%s" % (sequence_name, self.name)
|
sequence_id = "%s.%s" % (sequence_name, self.name)
|
||||||
collection = get_db(alias=self.db_alias)[self.collection_name]
|
collection = get_db(alias=self.db_alias)[self.collection_name]
|
||||||
counter = collection.find_and_modify(query={"_id": sequence_id},
|
counter = collection.find_one_and_update(
|
||||||
update={"$set": {"next": value}},
|
filter={"_id": sequence_id},
|
||||||
new=True,
|
update={"$set": {"next": value}},
|
||||||
upsert=True)
|
return_document=ReturnDocument.AFTER,
|
||||||
|
upsert=True)
|
||||||
return self.value_decorator(counter['next'])
|
return self.value_decorator(counter['next'])
|
||||||
|
|
||||||
def get_next_value(self):
|
def get_next_value(self):
|
||||||
|
@@ -481,9 +481,10 @@ class BaseQuerySet(object):
|
|||||||
write_concern=write_concern,
|
write_concern=write_concern,
|
||||||
**{'pull_all__%s' % field_name: self})
|
**{'pull_all__%s' % field_name: self})
|
||||||
|
|
||||||
result = queryset._collection.remove(queryset._query, **write_concern)
|
with set_write_concern(queryset._collection, write_concern) as collection:
|
||||||
if result:
|
result = collection.delete_many(queryset._query)
|
||||||
return result.get('n')
|
if result.acknowledged:
|
||||||
|
return result.deleted_count
|
||||||
|
|
||||||
def update(self, upsert=False, multi=True, write_concern=None,
|
def update(self, upsert=False, multi=True, write_concern=None,
|
||||||
full_result=False, **update):
|
full_result=False, **update):
|
||||||
|
@@ -3525,76 +3525,5 @@ class InstanceTest(MongoDBTestCase):
|
|||||||
User.objects().select_related()
|
User.objects().select_related()
|
||||||
|
|
||||||
|
|
||||||
class DocumentToDictTest(MongoDBTestCase):
|
|
||||||
"""Class for testing the BaseDocument.to_dict method."""
|
|
||||||
|
|
||||||
def test_to_dict(self):
|
|
||||||
class Person(Document):
|
|
||||||
name = StringField()
|
|
||||||
age = IntField()
|
|
||||||
|
|
||||||
p = Person(name='Tom', age=30)
|
|
||||||
self.assertEqual(p.to_dict(), {'id': None, 'name': 'Tom', 'age': 30})
|
|
||||||
|
|
||||||
def test_to_dict_with_a_persisted_doc(self):
|
|
||||||
class Person(Document):
|
|
||||||
name = StringField()
|
|
||||||
age = IntField()
|
|
||||||
|
|
||||||
p = Person.objects.create(name='Tom', age=30)
|
|
||||||
p_dict = p.to_dict()
|
|
||||||
self.assertTrue(p_dict['id'])
|
|
||||||
self.assertEqual(p_dict['name'], 'Tom')
|
|
||||||
self.assertEqual(p_dict['age'], 30)
|
|
||||||
|
|
||||||
def test_to_dict_empty_doc(self):
|
|
||||||
class Person(Document):
|
|
||||||
name = StringField()
|
|
||||||
age = IntField()
|
|
||||||
|
|
||||||
p = Person()
|
|
||||||
self.assertEqual(p.to_dict(), {'id': None, 'name': None, 'age': None})
|
|
||||||
|
|
||||||
def test_to_dict_with_default_values(self):
|
|
||||||
class Person(Document):
|
|
||||||
name = StringField(default='Unknown')
|
|
||||||
age = IntField(default=0)
|
|
||||||
|
|
||||||
p = Person()
|
|
||||||
self.assertEqual(
|
|
||||||
p.to_dict(),
|
|
||||||
{'id': None, 'name': 'Unknown', 'age': 0}
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_to_dict_with_a_db_field(self):
|
|
||||||
class Person(Document):
|
|
||||||
name = StringField(db_field='db_name')
|
|
||||||
|
|
||||||
p = Person(name='Tom')
|
|
||||||
self.assertEqual(p.to_dict(), {'id': None, 'name': 'Tom'})
|
|
||||||
|
|
||||||
def test_to_dict_with_a_primary_key(self):
|
|
||||||
class Person(Document):
|
|
||||||
username = StringField(primary_key=True)
|
|
||||||
|
|
||||||
p = Person(username='tomtom')
|
|
||||||
self.assertEqual(p.to_dict(), {'username': 'tomtom'})
|
|
||||||
|
|
||||||
def test_to_dict_with_an_embedded_document(self):
|
|
||||||
class Book(EmbeddedDocument):
|
|
||||||
title = StringField()
|
|
||||||
|
|
||||||
class Author(Document):
|
|
||||||
name = StringField()
|
|
||||||
book = EmbeddedDocumentField(Book)
|
|
||||||
|
|
||||||
a = Author(name='Yuval', book=Book(title='Sapiens'))
|
|
||||||
self.assertEqual(a.to_dict(), {
|
|
||||||
'id': None,
|
|
||||||
'name': 'Yuval',
|
|
||||||
'book': {'title': 'Sapiens'}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
@@ -1857,8 +1857,8 @@ class QuerySetTest(unittest.TestCase):
|
|||||||
self.Person.objects()[:1].delete()
|
self.Person.objects()[:1].delete()
|
||||||
self.assertEqual(1, BlogPost.objects.count())
|
self.assertEqual(1, BlogPost.objects.count())
|
||||||
|
|
||||||
def test_limit_with_write_concern_0(self):
|
def test_delete_edge_case_with_write_concern_0_return_None(self):
|
||||||
|
"""Return None when write is unacknowledged"""
|
||||||
p1 = self.Person(name="User Z", age=20).save()
|
p1 = self.Person(name="User Z", age=20).save()
|
||||||
del_result = p1.delete(w=0)
|
del_result = p1.delete(w=0)
|
||||||
self.assertEqual(None, del_result)
|
self.assertEqual(None, del_result)
|
||||||
|
Reference in New Issue
Block a user