diff options
| author | Tom Christie | 2013-03-19 14:26:48 +0000 | 
|---|---|---|
| committer | Tom Christie | 2013-03-19 14:26:48 +0000 | 
| commit | b2dc66448503c2120d943a2f282eab235afc67ba (patch) | |
| tree | 8115409050b9cc13eac7e6f1e32f7e6014006692 /rest_framework/serializers.py | |
| parent | 09e4ee7ae332326e77b23bac1539d31e582419e9 (diff) | |
| download | django-rest-framework-b2dc66448503c2120d943a2f282eab235afc67ba.tar.bz2 | |
Basic bulk create and bulk update
Diffstat (limited to 'rest_framework/serializers.py')
| -rw-r--r-- | rest_framework/serializers.py | 38 | 
1 files changed, 38 insertions, 0 deletions
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 4fe857a6..34120dc6 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -128,6 +128,7 @@ class BaseSerializer(Field):          self._data = None          self._files = None          self._errors = None +        self._deleted = None      #####      # Methods to determine which fields to use when (de)serializing objects. @@ -331,6 +332,13 @@ class BaseSerializer(Field):              return [self.to_native(item) for item in obj]          return self.to_native(obj) +    def get_identity(self, data): +        """ +        This hook is required for bulk update. +        It is used to determine the canonical identity of a given object. +        """ +        return data.get('id') +      @property      def errors(self):          """ @@ -352,9 +360,32 @@ class BaseSerializer(Field):              if many:                  ret = []                  errors = [] +                update = self.object is not None + +                if update: +                    # If this is a bulk update we need to map all the objects +                    # to a canonical identity so we can determine which +                    # individual object is being updated for each item in the +                    # incoming data +                    objects = self.object +                    identities = [self.get_identity(self.to_native(obj)) for obj in objects] +                    identity_to_objects = dict(zip(identities, objects)) +                  for item in data: +                    if update: +                        # Determine which object we're updating +                        try: +                            identity = self.get_identity(item) +                        except: +                            self.object = None +                        else: +                            self.object = identity_to_objects.pop(identity, None) +                      ret.append(self.from_native(item, None))                      errors.append(self._errors) + +                if update: +                    self._deleted = identity_to_objects.values()                  self._errors = any(errors) and errors or []              else:                  ret = self.from_native(data, files) @@ -394,6 +425,9 @@ class BaseSerializer(Field):      def save_object(self, obj, **kwargs):          obj.save(**kwargs) +    def delete_object(self, obj): +        obj.delete() +      def save(self, **kwargs):          """          Save the deserialized object and return it. @@ -402,6 +436,10 @@ class BaseSerializer(Field):              [self.save_object(item, **kwargs) for item in self.object]          else:              self.save_object(self.object, **kwargs) + +        if self._deleted: +            [self.delete_object(item) for item in self._deleted] +          return self.object  | 
