Quellcode durchsuchen

added BulkListSerializer and BulkSerializerMixin to add DRF3 support

Miroslav Shubernetskiy vor 10 Jahren
Ursprung
Commit
43f7b14296

+ 15 - 0
rest_framework_bulk/drf2/serializers.py

@@ -0,0 +1,15 @@
+from __future__ import print_function, unicode_literals
+
+
+__all__ = [
+    'BulkListSerializer',
+    'BulkSerializerMixin',
+]
+
+
+class BulkSerializerMixin(object):
+    pass
+
+
+class BulkListSerializer(object):
+    pass

+ 53 - 0
rest_framework_bulk/drf3/serializers.py

@@ -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

+ 12 - 0
rest_framework_bulk/serializers.py

@@ -0,0 +1,12 @@
+from __future__ import print_function, unicode_literals
+import rest_framework
+
+
+# import appropriate mixins depending on the DRF version
+# this allows to maintain clean code for each DRF version
+# without doing any magic
+# a little more code but a lit clearer what is going on
+if str(rest_framework.__version__).startswith('2'):
+    from .drf2.serializers import *  # noqa
+else:
+    from .drf3.serializers import *  # noqa

+ 5 - 1
rest_framework_bulk/tests/simple_app/serializers.py

@@ -1,9 +1,13 @@
 from __future__ import print_function, unicode_literals
 from rest_framework.serializers import ModelSerializer
+from rest_framework_bulk.serializers import BulkListSerializer, BulkSerializerMixin
 
 from .models import SimpleModel
 
 
-class SimpleSerializer(ModelSerializer):
+class SimpleSerializer(BulkSerializerMixin,  # only required in DRF3
+                       ModelSerializer):
     class Meta(object):
         model = SimpleModel
+        # only required in DRF3
+        list_serializer_class = BulkListSerializer