Skip to content

Commit e143b45

Browse files
committed
allow QuerySet.count() to query multiple collections
1 parent 4f52df0 commit e143b45

File tree

2 files changed

+22
-10
lines changed

2 files changed

+22
-10
lines changed

django_mongodb/features.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
9191
"annotations.tests.NonAggregateAnnotationTestCase.test_annotation_with_m2m",
9292
"annotations.tests.NonAggregateAnnotationTestCase.test_chaining_annotation_filter_with_m2m",
9393
"annotations.tests.NonAggregateAnnotationTestCase.test_mti_annotations",
94-
"lookup.tests.LookupTests.test_lookup_collision",
9594
"expressions.test_queryset_values.ValuesExpressionsTests.test_values_list_expression",
9695
"expressions.test_queryset_values.ValuesExpressionsTests.test_values_list_expression_flat",
9796
"expressions_case.tests.CaseExpressionTests.test_join_promotion",
@@ -382,6 +381,8 @@ def django_test_expected_failures(self):
382381
"timezones.tests.NewDatabaseTests.test_query_datetimes_in_other_timezone",
383382
},
384383
"QuerySet.distinct() is not supported.": {
384+
# TODO: remove underscore before merge
385+
"lookup.tests.LookupTests._test_lookup_collision_distinct",
385386
"update.tests.AdvancedTests.test_update_all",
386387
},
387388
"QuerySet.extra() is not supported.": {

django_mongodb/query.py

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,8 @@ def count(self, limit=None, skip=None):
6060
Return the number of objects that would be returned, if this query was
6161
executed, up to `limit`, skipping `skip`.
6262
"""
63-
kwargs = {}
64-
if limit is not None:
65-
kwargs["limit"] = limit
66-
if skip is not None:
67-
kwargs["skip"] = skip
68-
return self.collection.count_documents(self.mongo_query, **kwargs)
63+
result = list(self.get_cursor(count=True, limit=limit, skip=skip))
64+
return result[0]["__count"] if result else 0
6965

7066
def order_by(self, ordering):
7167
"""
@@ -91,7 +87,16 @@ def delete(self):
9187
options = self.connection.operation_flags.get("delete", {})
9288
return self.collection.delete_many(self.mongo_query, **options).deleted_count
9389

94-
def get_cursor(self):
90+
def get_cursor(self, count=False, limit=None, skip=None):
91+
"""
92+
Return a pymongo CommandCursor that can be iterated on to give the
93+
results of the query.
94+
95+
If `count` is True, return a single document with the number of
96+
documents that match the query.
97+
98+
Use `limit` or `skip` to override those options of the query.
99+
"""
95100
if self.query.low_mark == self.query.high_mark:
96101
return []
97102
fields = {}
@@ -125,10 +130,16 @@ def get_cursor(self):
125130
pipeline.append({"$project": fields})
126131
if self.ordering:
127132
pipeline.append({"$sort": dict(self.ordering)})
128-
if self.query.low_mark > 0:
133+
if skip is not None:
134+
pipeline.append({"$skip": skip})
135+
elif self.query.low_mark > 0:
129136
pipeline.append({"$skip": self.query.low_mark})
130-
if self.query.high_mark is not None:
137+
if limit is not None:
138+
pipeline.append({"$limit": limit})
139+
elif self.query.high_mark is not None:
131140
pipeline.append({"$limit": self.query.high_mark - self.query.low_mark})
141+
if count:
142+
pipeline.append({"$group": {"_id": None, "__count": {"$sum": 1}}})
132143
return self.collection.aggregate(pipeline)
133144

134145

0 commit comments

Comments
 (0)