@@ -153,6 +153,61 @@ def test_validate_html_input(self):
153
153
assert serializer .is_valid ()
154
154
assert serializer .validated_data == expected_output
155
155
156
+ def test_update_allow_custom_child_validation (self ):
157
+ """
158
+ Update a list of objects thanks custom run_child_validation implementation.
159
+ """
160
+
161
+ class TestUpdateSerializer (serializers .Serializer ):
162
+ integer = serializers .IntegerField ()
163
+ boolean = serializers .BooleanField ()
164
+
165
+ def update (self , instance , validated_data ):
166
+ instance ._data .update (validated_data )
167
+ return instance
168
+
169
+ def validate (self , data ):
170
+ # self.instance is set to current BasicObject instance
171
+ assert isinstance (self .instance , BasicObject )
172
+ # self.initial_data is current dictionary
173
+ assert isinstance (self .initial_data , dict )
174
+ assert self .initial_data ["pk" ] == self .instance .pk
175
+ return super ().validate (data )
176
+
177
+ class ListUpdateSerializer (serializers .ListSerializer ):
178
+ child = TestUpdateSerializer ()
179
+
180
+ def run_child_validation (self , data ):
181
+ # find related instance in self.instance list
182
+ child_instance = next (o for o in self .instance if o .pk == data ["pk" ])
183
+ # set instance and initial_data for child serializer
184
+ self .child .instance = child_instance
185
+ self .child .initial_data = data
186
+ return super ().run_child_validation (data )
187
+
188
+ def update (self , instance , validated_data ):
189
+ return [
190
+ self .child .update (instance , attrs )
191
+ for instance , attrs in zip (self .instance , validated_data )
192
+ ]
193
+
194
+ instance = [
195
+ BasicObject (pk = 1 , integer = 11 , private_field = "a" ),
196
+ BasicObject (pk = 2 , integer = 22 , private_field = "b" ),
197
+ ]
198
+ input_data = [
199
+ {"pk" : 1 , "integer" : "123" , "boolean" : "true" },
200
+ {"pk" : 2 , "integer" : "456" , "boolean" : "false" },
201
+ ]
202
+ expected_output = [
203
+ BasicObject (pk = 1 , integer = 123 , boolean = True , private_field = "a" ),
204
+ BasicObject (pk = 2 , integer = 456 , boolean = False , private_field = "b" ),
205
+ ]
206
+ serializer = ListUpdateSerializer (instance , data = input_data )
207
+ assert serializer .is_valid ()
208
+ updated_instances = serializer .save ()
209
+ assert updated_instances == expected_output
210
+
156
211
157
212
class TestNestedListSerializer :
158
213
"""
@@ -481,7 +536,7 @@ class Serializer(serializers.Serializer):
481
536
assert serializer .validated_data == {}
482
537
assert serializer .errors == {}
483
538
484
- def test_udate_as_field_allow_empty_true (self ):
539
+ def test_update_as_field_allow_empty_true (self ):
485
540
class ListSerializer (serializers .Serializer ):
486
541
update_field = serializers .IntegerField ()
487
542
store_field = serializers .IntegerField ()
0 commit comments