|  | @@ -0,0 +1,53 @@
 | 
	
		
			
				|  |  | +from __future__ import print_function, unicode_literals
 | 
	
		
			
				|  |  | +from rest_framework.serializers import ListSerializer
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +__all__ = [
 | 
	
		
			
				|  |  | +    'BulkListSerializer',
 | 
	
		
			
				|  |  | +    'BulkSerializerMixin',
 | 
	
		
			
				|  |  | +]
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +class BulkSerializerMixin(object):
 | 
	
		
			
				|  |  | +    def to_internal_value(self, data):
 | 
	
		
			
				|  |  | +        ret = super(BulkSerializerMixin, self).to_internal_value(data)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        id_attr = getattr(self.Meta, 'update_lookup_field', 'id')
 | 
	
		
			
				|  |  | +        request_method = getattr(getattr(self.context.get('view'), 'request'), 'method', '')
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        # add update_lookup_field field back to validated data
 | 
	
		
			
				|  |  | +        # since super by default strips out read-only fields
 | 
	
		
			
				|  |  | +        # hence id will no longer be present in validated_data
 | 
	
		
			
				|  |  | +        if all((isinstance(self.root, BulkListSerializer),
 | 
	
		
			
				|  |  | +                id_attr,
 | 
	
		
			
				|  |  | +                request_method in ('PUT', 'PATCH'))):
 | 
	
		
			
				|  |  | +            id_field = self.fields[id_attr]
 | 
	
		
			
				|  |  | +            id_value = id_field.get_value(data)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            ret[id_attr] = id_value
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return ret
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +class BulkListSerializer(ListSerializer):
 | 
	
		
			
				|  |  | +    update_lookup_field = 'id'
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def update(self, instances, all_validated_data):
 | 
	
		
			
				|  |  | +        id_attr = getattr(self.child.Meta, 'update_lookup_field', 'id')
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        all_validated_data_by_id = {
 | 
	
		
			
				|  |  | +            i.pop(id_attr): i
 | 
	
		
			
				|  |  | +            for i in all_validated_data
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        updated_objects = []
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        for obj in instances:
 | 
	
		
			
				|  |  | +            obj_id = getattr(obj, id_attr, None)
 | 
	
		
			
				|  |  | +            obj_validated_data = all_validated_data_by_id.get(obj_id)
 | 
	
		
			
				|  |  | +            if obj_id and obj_validated_data:
 | 
	
		
			
				|  |  | +                # use model serializer to actually update the model
 | 
	
		
			
				|  |  | +                # in case that method is overwritten
 | 
	
		
			
				|  |  | +                updated_objects.append(self.child.update(obj, obj_validated_data))
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return updated_objects
 |