23
23
)
24
24
25
25
26
+ def truncate_ms (value ):
27
+ """Truncate microsends to millisecond precision as supported by MongoDB."""
28
+ return value .replace (microsecond = (value .microsecond // 1000 ) * 1000 )
29
+
30
+
26
31
class MethodTests (SimpleTestCase ):
27
32
def test_deconstruct (self ):
28
33
field = EmbeddedModelField ("Data" , null = True )
@@ -46,10 +51,6 @@ def test_validate(self):
46
51
47
52
48
53
class ModelTests (TestCase ):
49
- def truncate_ms (self , value ):
50
- """Truncate microseconds to milliseconds as supported by MongoDB."""
51
- return value .replace (microsecond = (value .microsecond // 1000 ) * 1000 )
52
-
53
54
def test_save_load (self ):
54
55
Holder .objects .create (data = Data (integer = "5" ))
55
56
obj = Holder .objects .get ()
@@ -72,12 +73,12 @@ def test_save_load_null(self):
72
73
def test_pre_save (self ):
73
74
"""Field.pre_save() is called on embedded model fields."""
74
75
obj = Holder .objects .create (data = Data ())
75
- auto_now = self . truncate_ms (obj .data .auto_now )
76
- auto_now_add = self . truncate_ms (obj .data .auto_now_add )
76
+ auto_now = truncate_ms (obj .data .auto_now )
77
+ auto_now_add = truncate_ms (obj .data .auto_now_add )
77
78
self .assertEqual (auto_now , auto_now_add )
78
79
# save() updates auto_now but not auto_now_add.
79
80
obj .save ()
80
- self .assertEqual (self . truncate_ms (obj .data .auto_now_add ), auto_now_add )
81
+ self .assertEqual (truncate_ms (obj .data .auto_now_add ), auto_now_add )
81
82
auto_now_two = obj .data .auto_now
82
83
self .assertGreater (auto_now_two , obj .data .auto_now_add )
83
84
# And again, save() updates auto_now but not auto_now_add.
@@ -107,52 +108,54 @@ def test_gt(self):
107
108
def test_gte (self ):
108
109
self .assertCountEqual (Holder .objects .filter (data__integer__gte = 3 ), self .objs [3 :])
109
110
110
- def test_nested (self ):
111
- obj = Book .objects .create (
112
- author = Author (name = "Shakespeare" , age = 55 , address = Address (city = "NYC" , state = "NY" ))
113
- )
114
- self .assertCountEqual (Book .objects .filter (author__address__city = "NYC" ), [obj ])
115
-
116
- def truncate_ms (self , value ):
117
- """Truncate microsends to millisecond precision as supported by MongoDB."""
118
- return value .replace (microsecond = (value .microsecond // 1000 ) * 1000 )
119
-
120
111
def test_ordering_by_embedded_field (self ):
121
112
query = Holder .objects .filter (data__integer__gt = 3 ).order_by ("-data__integer" ).values ("pk" )
122
113
expected = [{"pk" : e .pk } for e in list (reversed (self .objs [4 :]))]
123
114
self .assertSequenceEqual (query , expected )
124
115
125
116
def test_ordering_grouping_by_embedded_field (self ):
126
- expected = sorted (
117
+ # Create and sort test data by `data__integer`
118
+ expected_obj = sorted (
127
119
(Holder .objects .create (data = Data (integer = x )) for x in range (6 )),
128
120
key = lambda x : x .data .integer ,
129
121
)
130
- query = (
122
+ # Group by `data__integer + 5` and get the latest `data__auto_now` timestamp
123
+ qs = (
131
124
Holder .objects .annotate (
132
125
group = ExpressionWrapper (F ("data__integer" ) + 5 , output_field = IntegerField ())
133
126
)
134
127
.values ("group" )
135
128
.annotate (max_auto_now = Max ("data__auto_now" ))
136
129
.order_by ("data__integer" )
137
130
)
138
- query_response = [{** e , "max_auto_now" : self .truncate_ms (e ["max_auto_now" ])} for e in query ]
131
+ response = [{** e , "max_auto_now" : e ["max_auto_now" ]} for e in qs ]
132
+ # Validate that each unique `data__integer` is correctly grouped and annotated
139
133
self .assertSequenceEqual (
140
- query_response ,
134
+ response ,
141
135
[
142
- {"group" : e .data .integer + 5 , "max_auto_now" : self . truncate_ms (e .data .auto_now )}
143
- for e in expected
136
+ {"group" : e .data .integer + 5 , "max_auto_now" : truncate_ms (e .data .auto_now )}
137
+ for e in expected_obj
144
138
],
145
139
)
146
140
147
141
def test_ordering_grouping_by_sum (self ):
142
+ # Create test data with repeated `data__integer` values
148
143
[Holder .objects .create (data = Data (integer = x )) for x in range (6 )]
144
+ # Group by `data__integer` and compute the sum of occurrences
149
145
qs = (
150
146
Holder .objects .values ("data__integer" )
151
147
.annotate (sum = Sum ("data__integer" ))
152
148
.order_by ("sum" )
153
149
)
150
+ # The sum should be twice the integer values (since each appears twice)
154
151
self .assertQuerySetEqual (qs , [0 , 2 , 4 , 6 , 8 , 10 ], operator .itemgetter ("sum" ))
155
152
153
+ def test_nested (self ):
154
+ obj = Book .objects .create (
155
+ author = Author (name = "Shakespeare" , age = 55 , address = Address (city = "NYC" , state = "NY" ))
156
+ )
157
+ self .assertCountEqual (Book .objects .filter (author__address__city = "NYC" ), [obj ])
158
+
156
159
157
160
@isolate_apps ("model_fields_" )
158
161
class CheckTests (SimpleTestCase ):
0 commit comments