groundwork for deferred fields

This commit is contained in:
blackbrrr 2010-01-14 11:39:03 -06:00
parent b375c41586
commit 7e0fcb9e65
3 changed files with 44 additions and 2 deletions

View File

@ -344,8 +344,12 @@ class BaseDocument(object):
return None
cls = subclasses[class_name]
present_fields = data.keys()
for field_name, field in cls._fields.items():
if field.name in data:
data[field_name] = field.to_python(data[field.name])
return cls(**data)
obj = cls(**data)
obj._present_fields = present_fields
return obj

View File

@ -112,6 +112,7 @@ class QuerySet(object):
self._accessed_collection = False
self._query = {}
self._where_clauses = []
self._field_subset = []
# If inheritance is allowed, only return instances and instances of
# subclasses of the class being used
@ -188,7 +189,12 @@ class QuerySet(object):
@property
def _cursor(self):
if not self._cursor_obj:
self._cursor_obj = self._collection.find(self._query)
query_kwargs = {}
if self._field_subset:
# load only a subset of fields
query_kwargs['fields'] = self._field_subset
self._cursor_obj = self._collection.find(self._query, **query_kwargs)
# Apply where clauses to cursor
for js in self._where_clauses:
self._cursor_obj.where(js)
@ -334,6 +340,14 @@ class QuerySet(object):
elif isinstance(key, int):
return self._document._from_son(self._cursor[key])
def only(self, *fields):
"""Allow only a subset of fields to be loaded. Invalid fields
are silently ignored.
"""
fields = list(fields)
self._field_subset = fields
return self
def order_by(self, *keys):
"""Order the :class:`~mongoengine.queryset.QuerySet` by the keys. The
order may be specified by prepending each of the keys by a + or a -.

View File

@ -171,6 +171,30 @@ class QuerySetTest(unittest.TestCase):
BlogPost.drop_collection()
def test_field_subsets(self):
"""Ensure that a call to ``only`` loads only selected fields.
"""
class DinerReview(Document):
title = StringField()
abstract = StringField()
content = StringField()
review = DinerReview(title="Lorraine's Diner")
review.abstract = "Dirty dishes, great food."
review.content = """
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Mauris eu felis risus, eget congue ante. Mauris consectetur
dignissim velit, quis dictum risus tincidunt ac.
Phasellus condimentum imperdiet laoreet.
"""
review.save()
review = DinerReview.objects.only("title").first()
self.assertEqual(review.content, None)
DinerReview.drop_collection()
def test_ordering(self):
"""Ensure default ordering is applied and can be overridden.
"""