Skip to content

Commit

Permalink
add support for annotations, group by, and ordering
Browse files Browse the repository at this point in the history
  • Loading branch information
timgraham authored and WaVEV committed Jan 18, 2025
1 parent fd57ce8 commit d7d40c3
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 2 deletions.
4 changes: 2 additions & 2 deletions django_mongodb_backend/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def _get_column_from_expression(self, expr, alias):
Create a column named `alias` from the given expression to hold the
aggregate value.
"""
column_target = expr.output_field.__class__()
column_target = expr.output_field.clone()
column_target.db_column = alias
column_target.set_attributes_from_name(alias)
return Col(self.collection_name, column_target)
Expand Down Expand Up @@ -81,7 +81,7 @@ def _prepare_expressions_for_pipeline(self, expression, target, annotation_group
alias = (
f"__aggregation{next(annotation_group_idx)}" if sub_expr != expression else target
)
column_target = sub_expr.output_field.__class__()
column_target = sub_expr.output_field.clone()
column_target.db_column = alias
column_target.set_attributes_from_name(alias)
inner_column = Col(self.collection_name, column_target)
Expand Down
49 changes: 49 additions & 0 deletions tests/model_fields_/test_embedded_model.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
import operator

from django.core.exceptions import ValidationError
from django.db import models
from django.db.models import (
ExpressionWrapper,
F,
IntegerField,
Max,
Sum,
)
from django.test import SimpleTestCase, TestCase
from django.test.utils import isolate_apps

Expand Down Expand Up @@ -104,6 +113,46 @@ def test_nested(self):
)
self.assertCountEqual(Book.objects.filter(author__address__city="NYC"), [obj])

def truncate_ms(self, value):
"""Truncate microsends to millisecond precision as supported by MongoDB."""
return value.replace(microsecond=(value.microsecond // 1000) * 1000)

def test_ordering_by_embedded_field(self):
query = Holder.objects.filter(data__integer__gt=3).order_by("-data__integer").values("pk")
expected = [{"pk": e.pk} for e in list(reversed(self.objs[4:]))]
self.assertSequenceEqual(query, expected)

def test_ordering_grouping_by_embedded_field(self):
expected = sorted(
(Holder.objects.create(data=Data(integer=x)) for x in range(6)),
key=lambda x: x.data.integer,
)
query = (
Holder.objects.annotate(
group=ExpressionWrapper(F("data__integer") + 5, output_field=IntegerField())
)
.values("group")
.annotate(max_auto_now=Max("data__auto_now"))
.order_by("data__integer")
)
query_response = [{**e, "max_auto_now": self.truncate_ms(e["max_auto_now"])} for e in query]
self.assertSequenceEqual(
query_response,
[
{"group": e.data.integer + 5, "max_auto_now": self.truncate_ms(e.data.auto_now)}
for e in expected
],
)

def test_ordering_grouping_by_sum(self):
[Holder.objects.create(data=Data(integer=x)) for x in range(6)]
qs = (
Holder.objects.values("data__integer")
.annotate(sum=Sum("data__integer"))
.order_by("sum")
)
self.assertQuerySetEqual(qs, [0, 2, 4, 6, 8, 10], operator.itemgetter("sum"))


@isolate_apps("model_fields_")
class CheckTests(SimpleTestCase):
Expand Down

0 comments on commit d7d40c3

Please sign in to comment.