exec_js functions now acknowledge Q objects
This commit is contained in:
parent
21b7d8f8ea
commit
470e08f616
@ -1,6 +1,6 @@
|
|||||||
include README.rst
|
include README.rst
|
||||||
include LICENSE
|
include LICENSE
|
||||||
recursive-include docs *
|
recursive-include docs *
|
||||||
prune docs/_build/*
|
prune docs/_build
|
||||||
recursive-include tests *
|
recursive-include tests *
|
||||||
recursive-exclude * *.pyc *.swp
|
recursive-exclude * *.pyc *.swp
|
||||||
|
@ -142,8 +142,8 @@ A :class:`~mongoengine.queryset.Q` object represents part of a query, and
|
|||||||
can be initialised using the same keyword-argument syntax you use to query
|
can be initialised using the same keyword-argument syntax you use to query
|
||||||
documents. To build a complex query, you may combine
|
documents. To build a complex query, you may combine
|
||||||
:class:`~mongoengine.queryset.Q` objects using the ``&`` (and) and ``|`` (or)
|
:class:`~mongoengine.queryset.Q` objects using the ``&`` (and) and ``|`` (or)
|
||||||
operators. To use :class:`~mongoengine.queryset.Q` objects, pass them in
|
operators. To use a :class:`~mongoengine.queryset.Q` object, pass it in as the
|
||||||
as positional arguments to :attr:`Document.objects` when you filter it by
|
first positional argument to :attr:`Document.objects` when you filter it by
|
||||||
calling it with keyword arguments::
|
calling it with keyword arguments::
|
||||||
|
|
||||||
# Get published posts
|
# Get published posts
|
||||||
|
@ -111,7 +111,7 @@ class QuerySet(object):
|
|||||||
self._collection_obj = collection
|
self._collection_obj = collection
|
||||||
self._accessed_collection = False
|
self._accessed_collection = False
|
||||||
self._query = {}
|
self._query = {}
|
||||||
self._where_clauses = []
|
self._where_clause = None
|
||||||
|
|
||||||
# If inheritance is allowed, only return instances and instances of
|
# If inheritance is allowed, only return instances and instances of
|
||||||
# subclasses of the class being used
|
# subclasses of the class being used
|
||||||
@ -165,16 +165,18 @@ class QuerySet(object):
|
|||||||
|
|
||||||
return index_list
|
return index_list
|
||||||
|
|
||||||
def __call__(self, *q_objs, **query):
|
def __call__(self, q_obj=None, **query):
|
||||||
"""Filter the selected documents by calling the
|
"""Filter the selected documents by calling the
|
||||||
:class:`~mongoengine.queryset.QuerySet` with a query.
|
:class:`~mongoengine.queryset.QuerySet` with a query.
|
||||||
|
|
||||||
:param q_objs: :class:`~mongoengine.queryset.Q` objects to be used in
|
:param q_obj: a :class:`~mongoengine.queryset.Q` object to be used in
|
||||||
the query
|
the query; the :class:`~mongoengine.queryset.QuerySet` is filtered
|
||||||
|
multiple times with different :class:`~mongoengine.queryset.Q`
|
||||||
|
objects, only the last one will be used
|
||||||
:param query: Django-style query keyword arguments
|
:param query: Django-style query keyword arguments
|
||||||
"""
|
"""
|
||||||
for q in q_objs:
|
if q_obj:
|
||||||
self._where_clauses.append(q.as_js(self._document))
|
self._where_clause = q_obj.as_js(self._document)
|
||||||
query = QuerySet._transform_query(_doc_cls=self._document, **query)
|
query = QuerySet._transform_query(_doc_cls=self._document, **query)
|
||||||
self._query.update(query)
|
self._query.update(query)
|
||||||
return self
|
return self
|
||||||
@ -209,11 +211,11 @@ class QuerySet(object):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def _cursor(self):
|
def _cursor(self):
|
||||||
if not self._cursor_obj:
|
if self._cursor_obj is None:
|
||||||
self._cursor_obj = self._collection.find(self._query)
|
self._cursor_obj = self._collection.find(self._query)
|
||||||
# Apply where clauses to cursor
|
# Apply where clauses to cursor
|
||||||
for js in self._where_clauses:
|
if self._where_clause:
|
||||||
self._cursor_obj.where(js)
|
self._cursor_obj.where(self._where_clause)
|
||||||
|
|
||||||
# apply default ordering
|
# apply default ordering
|
||||||
if self._document._meta['ordering']:
|
if self._document._meta['ordering']:
|
||||||
@ -516,11 +518,17 @@ class QuerySet(object):
|
|||||||
fields = [QuerySet._translate_field_name(self._document, f)
|
fields = [QuerySet._translate_field_name(self._document, f)
|
||||||
for f in fields]
|
for f in fields]
|
||||||
collection = self._document._meta['collection']
|
collection = self._document._meta['collection']
|
||||||
|
|
||||||
scope = {
|
scope = {
|
||||||
'collection': collection,
|
'collection': collection,
|
||||||
'query': self._query,
|
|
||||||
'options': options or {},
|
'options': options or {},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query = self._query
|
||||||
|
if self._where_clause:
|
||||||
|
query['$where'] = self._where_clause
|
||||||
|
|
||||||
|
scope['query'] = query
|
||||||
code = pymongo.code.Code(code, scope=scope)
|
code = pymongo.code.Code(code, scope=scope)
|
||||||
|
|
||||||
db = _get_db()
|
db = _get_db()
|
||||||
|
@ -264,6 +264,50 @@ class QuerySetTest(unittest.TestCase):
|
|||||||
|
|
||||||
BlogPost.drop_collection()
|
BlogPost.drop_collection()
|
||||||
|
|
||||||
|
def test_exec_js_query(self):
|
||||||
|
"""Ensure that queries are properly formed for use in exec_js.
|
||||||
|
"""
|
||||||
|
class BlogPost(Document):
|
||||||
|
hits = IntField()
|
||||||
|
published = BooleanField()
|
||||||
|
|
||||||
|
BlogPost.drop_collection()
|
||||||
|
|
||||||
|
post1 = BlogPost(hits=1, published=False)
|
||||||
|
post1.save()
|
||||||
|
|
||||||
|
post2 = BlogPost(hits=1, published=True)
|
||||||
|
post2.save()
|
||||||
|
|
||||||
|
post3 = BlogPost(hits=1, published=True)
|
||||||
|
post3.save()
|
||||||
|
|
||||||
|
js_func = """
|
||||||
|
function(hitsField) {
|
||||||
|
var count = 0;
|
||||||
|
db[collection].find(query).forEach(function(doc) {
|
||||||
|
count += doc[hitsField];
|
||||||
|
});
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Ensure that normal queries work
|
||||||
|
c = BlogPost.objects(published=True).exec_js(js_func, 'hits')
|
||||||
|
self.assertEqual(c, 2)
|
||||||
|
|
||||||
|
c = BlogPost.objects(published=False).exec_js(js_func, 'hits')
|
||||||
|
self.assertEqual(c, 1)
|
||||||
|
|
||||||
|
# Ensure that Q object queries work
|
||||||
|
c = BlogPost.objects(Q(published=True)).exec_js(js_func, 'hits')
|
||||||
|
self.assertEqual(c, 2)
|
||||||
|
|
||||||
|
c = BlogPost.objects(Q(published=False)).exec_js(js_func, 'hits')
|
||||||
|
self.assertEqual(c, 1)
|
||||||
|
|
||||||
|
BlogPost.drop_collection()
|
||||||
|
|
||||||
def test_delete(self):
|
def test_delete(self):
|
||||||
"""Ensure that documents are properly deleted from the database.
|
"""Ensure that documents are properly deleted from the database.
|
||||||
"""
|
"""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user