Esempio n. 1
0
    def patch_detail(self, request, **kwargs):
        request = convert_post_to_patch(request)
        try:
            obj = self.cached_obj_get(request=request,
                                      **self.remove_api_resource_names(kwargs))
        except ObjectDoesNotExist:
            return http.HttpNotFound()
        except MultipleObjectsReturned:
            return http.HttpMultipleChoices('More than one resource'
                                            'is found at this URI.')

        bundle = self.build_bundle(obj=obj, request=request)
        bundle = self.full_dehydrate(bundle)
        bundle = self.alter_detail_data_to_serialize(request, bundle)

        # Now update the bundle in-place.
        deserialized = self.deserialize(request,
                                        request.raw_post_data,
                                        format=request.META.get(
                                            'CONTENT_TYPE',
                                            'application/json'))

        # In case of a patch modification, we need to store
        # the initial values for the given object to check
        # the Etag header.
        request.initial_etag = bundle.obj.etag
        return self.create_patch_response(request, bundle, deserialized)
Esempio n. 2
0
    def patch_detail(self, request, **kwargs):
        request = convert_post_to_patch(request)
        try:
            obj = self.cached_obj_get(
                request=request, **self.remove_api_resource_names(kwargs))
        except ObjectDoesNotExist:
            return http.HttpNotFound()
        except MultipleObjectsReturned:
            return http.HttpMultipleChoices('More than one resource'
                                            'is found at this URI.')

        bundle = self.build_bundle(obj=obj, request=request)
        bundle = self.full_dehydrate(bundle)
        bundle = self.alter_detail_data_to_serialize(request, bundle)

        # Now update the bundle in-place.
        deserialized = self.deserialize(
            request, request.body,
            format=request.META.get('CONTENT_TYPE', 'application/json'))

        # In case of a patch modification, we need to store
        # the initial values for the given object to check
        # the Etag header.
        request.initial_etag = bundle.obj.etag
        return self.create_patch_response(request, bundle, deserialized)
Esempio n. 3
0
 def patch_list(self, request, **kwargs):
     request = convert_post_to_patch(request)
     deserialized = self.deserialize(request,
                                     request.body,
                                     format=request.META.get(
                                         'CONTENT_TYPE',
                                         'application/json'))
     for data in deserialized["objects"]:
         data = self.alter_deserialized_detail_data(request, data)
         bundle = self.build_bundle(data=dict_strip_unicode_keys(data))
         bundle.request.user = request.user
         bundle.request.META['REMOTE_ADDR'] = request.META.get(
             'REMOTE_ADDR', '0.0.0.0')
         bundle.request.META['HTTP_USER_AGENT'] = request.META.get(
             'HTTP_USER_AGENT', 'unknown')
         self.obj_create(bundle, request=request)
     response_data = {
         'points': self.dehydrate_points(bundle),
         'badges': self.dehydrate_badges(bundle),
         'scoring': self.dehydrate_scoring(bundle),
         'badging': self.dehydrate_badging(bundle),
         'metadata': self.dehydrate_metadata(bundle),
         'course_points': self.dehydrate_course_points(bundle),
     }
     response = HttpResponse(content=json.dumps(response_data),
                             content_type="application/json; charset=utf-8")
     return response
Esempio n. 4
0
    def patch_list(self, request=None, **kwargs):
        """
        Exactly copied from https://github.com/toastdriven/django-tastypie/blob/v0.9.14/tastypie/resources.py#L1466
        (BSD licensed) and modified to pass the kwargs to `obj_create` and support only create method
        """
        request = convert_post_to_patch(request)
        deserialized = self.deserialize(request, request.body, format=request.META.get('CONTENT_TYPE', 'application/json'))

        collection_name = self._meta.collection_name
        if collection_name not in deserialized:
            raise BadRequest("Invalid data sent: missing '%s'" % collection_name)

        if len(deserialized[collection_name]) and 'put' not in self._meta.detail_allowed_methods:
            raise ImmediateHttpResponse(response=http.HttpMethodNotAllowed())

        bundles_seen = []
        status = http.HttpAccepted
        for data in deserialized[collection_name]:

            data = self.alter_deserialized_detail_data(request, data)
            bundle = self.build_bundle(data=dict_strip_unicode_keys(data), request=request)
            try:

                self.obj_create(bundle=bundle, **self.remove_api_resource_names(kwargs))
            except AssertionError as ex:
                status = http.HttpBadRequest
                bundle.data['_id'] = ex.message
            bundles_seen.append(bundle)

        to_be_serialized = [bundle.data['_id'] for bundle in bundles_seen]
        return self.create_response(request, to_be_serialized, response_class=status)
Esempio n. 5
0
    def patch_list(self, request=None, **kwargs):
        """
        Exactly copied from https://github.com/toastdriven/django-tastypie/blob/v0.9.14/tastypie/resources.py#L1466
        (BSD licensed) and modified to pass the kwargs to `obj_create` and support only create method
        """
        request = convert_post_to_patch(request)
        deserialized = self.deserialize(request, request.raw_post_data, format=request.META.get('CONTENT_TYPE', 'application/json'))

        collection_name = self._meta.collection_name
        if collection_name not in deserialized:
            raise BadRequest("Invalid data sent: missing '%s'" % collection_name)

        if len(deserialized[collection_name]) and 'put' not in self._meta.detail_allowed_methods:
            raise ImmediateHttpResponse(response=http.HttpMethodNotAllowed())

        bundles_seen = []
        status = http.HttpAccepted
        for data in deserialized[collection_name]:

            data = self.alter_deserialized_detail_data(request, data)
            bundle = self.build_bundle(data=dict_strip_unicode_keys(data), request=request)
            try:

                self.obj_create(bundle=bundle, **self.remove_api_resource_names(kwargs))
            except AssertionError as ex:
                status = http.HttpBadRequest
                bundle.data['_id'] = ex.message
            bundles_seen.append(bundle)

        to_be_serialized = [bundle.data['_id'] for bundle in bundles_seen]
        return self.create_response(request, to_be_serialized, response_class=status)
Esempio n. 6
0
    def patch_list(self, request, **kwargs):
        request = convert_post_to_patch(request)
        deserialized = self.deserialize(request, request.body,
                                        format=request.META.get('CONTENT_TYPE', 'application/json'))
        for data in deserialized.get("objects"):
            data = self.alter_deserialized_detail_data(request, data)
            bundle = self.build_bundle(data=dict_strip_unicode_keys(data))
            bundle.request.user = request.user
            bundle.request.META['REMOTE_ADDR'] = request.META.get('REMOTE_ADDR', api.DEFAULT_IP_ADDRESS)
            bundle.request.META['HTTP_USER_AGENT'] = request.META.get('HTTP_USER_AGENT', 'unknown')
            # check UUID not already submitted
            if 'data' in bundle.data:
                json_data = json.loads(bundle.data['data'])
                if 'uuid' in json_data:
                    uuids = Tracker.objects.filter(uuid=json_data['uuid'])
                    if uuids.count() == 0:
                        self.obj_create(bundle, request=request)
                else:
                    self.obj_create(bundle, request=request)
            else:
                self.obj_create(bundle, request=request)

        response_data = {'points': self.dehydrate_points(bundle),
                         'badges': self.dehydrate_badges(bundle),
                         'scoring': self.dehydrate_scoring(bundle),
                         'badging': self.dehydrate_badging(bundle),
                         'metadata': self.dehydrate_metadata(bundle),
                         'course_points': self.dehydrate_course_points(bundle),
                         }
        response = HttpResponse(content=json.dumps(response_data), content_type="application/json; charset=utf-8")
        return response
Esempio n. 7
0
 def patch_list(self, request, **kwargs):
     request = convert_post_to_patch(request)
     deserialized = self.deserialize(request,
                                     request.body,
                                     format=request.META.get('CONTENT_TYPE', 'application/json'))
     bundle = self.build_bundle(data=deserialized, request=request)
     return self.obj_update(bundle)
Esempio n. 8
0
    def patch_detail(self, request, **kwargs):

        pk = kwargs.get("pk")
        request = convert_post_to_patch(request)

        self.authorized_update_detail(
            Spirit.objects.filter(pk=pk),
            self.build_bundle(request=request)
        )

        form = PatchForm(
            request,
            get_object_or_404(Spirit, pk=pk),
            self.deserialize(
                request,
                request.body,
                format=request.META.get("CONTENT_TYPE", "application/json")
            )
        )

        if form.is_valid():
            form.save()
            return self.create_response(request, "", status=202)

        raise BadRequest(form.errors.as_text())
Esempio n. 9
0
    def patch_list(self, request, **kwargs):
        request = convert_post_to_patch(request)
        deserialized = self.deserialize(request, request.body,
                                        format=request.META.get('CONTENT_TYPE', 'application/json'))
        for data in deserialized["objects"]:
            data = self.alter_deserialized_detail_data(request, data)
            bundle = self.build_bundle(data=dict_strip_unicode_keys(data))
            bundle.request.user = request.user
            bundle.request.META['REMOTE_ADDR'] = request.META.get('REMOTE_ADDR', api.DEFAULT_IP_ADDRESS)
            bundle.request.META['HTTP_USER_AGENT'] = request.META.get('HTTP_USER_AGENT', 'unknown')
            # check UUID not already submitted
            if 'data' in bundle.data:
                json_data = json.loads(bundle.data['data'])
                if 'uuid' in json_data:
                    uuids = Tracker.objects.filter(uuid=json_data['uuid'])
                    if uuids.count() == 0:
                        self.obj_create(bundle, request=request)
                else:
                    self.obj_create(bundle, request=request)
            else:
                self.obj_create(bundle, request=request)

        response_data = {'points': self.dehydrate_points(bundle),
                         'badges': self.dehydrate_badges(bundle),
                         'scoring': self.dehydrate_scoring(bundle),
                         'badging': self.dehydrate_badging(bundle),
                         'metadata': self.dehydrate_metadata(bundle),
                         'course_points': self.dehydrate_course_points(bundle),
                         }
        response = HttpResponse(content=json.dumps(response_data), content_type="application/json; charset=utf-8")
        return response
Esempio n. 10
0
    def patch_detail(self, request, **kwargs):
        """
        Updates a resource in-place.

        Calls ``obj_update``.

        If the resource is updated, return ``HttpAccepted`` (202 Accepted).
        If the resource did not exist, return ``HttpNotFound`` (404 Not Found).
        """
        request = convert_post_to_patch(request)
        basic_bundle = self.build_bundle(request=request)

        # We want to be able to validate the update, but we can't just pass
        # the partial data into the validator since all data needs to be
        # present. Instead, we basically simulate a PUT by pulling out the
        # original data and updating it in-place.
        # So first pull out the original object. This is essentially
        # ``get_detail``.
        try:
            obj = self.cached_obj_get(bundle=basic_bundle,
                                      **self.remove_api_resource_names(kwargs))
        except ObjectDoesNotExist:
            return http.HttpNotFound()
        except MultipleObjectsReturned:
            return http.HttpMultipleChoices(
                "More than one resource is found at this URI.")

        self.post_obj_get(obj)

        bundle = self.build_bundle(obj=obj, request=request)
        bundle = self.full_dehydrate(bundle)
        bundle = self.alter_detail_data_to_serialize(request, bundle)

        # Now update the bundle in-place.
        deserialized = self.deserialize(request,
                                        request.body,
                                        format=request.META.get(
                                            'CONTENT_TYPE',
                                            'application/json'))
        self.update_in_place(request, bundle, deserialized)
        # TODO: Check if this try/except is neccessary
        #try:
        #    self.update_in_place(request, bundle, deserialized)
        #except ObjectDoesNotExist:
        #    return http.HttpNotFound()
        #

        if not self._meta.always_return_data:
            return http.HttpAccepted()
        else:
            bundle = self.full_dehydrate(bundle)
            bundle = self.alter_detail_data_to_serialize(request, bundle)
            return self.create_response(request,
                                        bundle,
                                        response_class=http.HttpAccepted)
Esempio n. 11
0
 def patch_list(self,request,**kwargs):
     request = convert_post_to_patch(request)
     deserialized = self.deserialize(request, request.raw_post_data, format=request.META.get('CONTENT_TYPE', 'application/json'))
     for data in deserialized["objects"]:
         data = self.alter_deserialized_detail_data(request, data)
         bundle = self.build_bundle(data=dict_strip_unicode_keys(data))
         bundle.request.user = request.user
         bundle.request.META['REMOTE_ADDR'] = request.META.get('REMOTE_ADDR','0.0.0.0')
         bundle.request.META['HTTP_USER_AGENT'] = request.META.get('HTTP_USER_AGENT','unknown')
         self.obj_create(bundle, request=request)
     response_data = {'points': self.dehydrate_points(bundle),'badges':self.dehydrate_badges(bundle)}
     response = HttpResponse(content=json.dumps(response_data),content_type="application/json; charset=utf-8")
     return response
Esempio n. 12
0
    def patch_list(self, request, **kwargs):
        response = super(SSEMixin, self).patch_list(request, **kwargs)

        patch = convert_post_to_patch(request)
        data = self.deserialize(patch, patch.body)

        try:
            objects = data.get('objects', [])
            container = Container.objects.get(pk=data.get('container_id'))
            notify.delay(objects, type="json", container=container, user=request.user)
        except Exception as e:
            logger.error("Impossible to create notification {}, {}".format(data, e))

        return response
Esempio n. 13
0
    def patch_detail(self, request, **kwargs):
        """
        Updates a resource in-place.

        Calls ``obj_update``.

        If the resource is updated, return ``HttpAccepted`` (202 Accepted).
        If the resource did not exist, return ``HttpNotFound`` (404 Not Found).
        """
        request = convert_post_to_patch(request)
        basic_bundle = self.build_bundle(request=request)

        # We want to be able to validate the update, but we can't just pass
        # the partial data into the validator since all data needs to be
        # present. Instead, we basically simulate a PUT by pulling out the
        # original data and updating it in-place.
        # So first pull out the original object. This is essentially
        # ``get_detail``.
        try:
            obj = self.cached_obj_get(bundle=basic_bundle, **self.remove_api_resource_names(kwargs))
        except ObjectDoesNotExist:
            return http.HttpNotFound()
        except MultipleObjectsReturned:
            return http.HttpMultipleChoices("More than one resource is found at this URI.")

        self.post_obj_get(obj)

        bundle = self.build_bundle(obj=obj, request=request)
        bundle = self.full_dehydrate(bundle)
        bundle = self.alter_detail_data_to_serialize(request, bundle)

        # Now update the bundle in-place.
        deserialized = self.deserialize(request, request.body, format=request.META.get('CONTENT_TYPE', 'application/json'))
        self.update_in_place(request, bundle, deserialized)
        # TODO: Check if this try/except is neccessary
        #try:
        #    self.update_in_place(request, bundle, deserialized)
        #except ObjectDoesNotExist:
        #    return http.HttpNotFound()
        #

        if not self._meta.always_return_data:
            return http.HttpAccepted()
        else:
            bundle = self.full_dehydrate(bundle)
            bundle = self.alter_detail_data_to_serialize(request, bundle)
            return self.create_response(request, bundle, response_class=http.HttpAccepted)
Esempio n. 14
0
    def patch_detail(self, request, **kwargs):
        request = convert_post_to_patch(request)
        basic_bundle = self.build_bundle(request=request)

        # We want to be able to validate the update, but we can't just pass
        # the partial data into the validator since all data needs to be
        # present. Instead, we basically simulate a PUT by pulling out the
        # original data and updating it in-place.
        # So first pull out the original object. This is essentially
        # ``get_detail``.
        try:
            obj = self.cached_obj_get(bundle=basic_bundle,
                                      **self.remove_api_resource_names(kwargs))
        except ObjectDoesNotExist:
            return http.HttpNotFound()
        except MultipleObjectsReturned:
            return http.HttpMultipleChoices(
                "More than one resource is found at this URI.")

        bundle = self.build_bundle(obj=obj, request=request)
        bundle = self.full_dehydrate(bundle)
        bundle = self.alter_detail_data_to_serialize(request, bundle)

        # Now update the bundle in-place.
        deserialized = self.deserialize(request,
                                        request.body,
                                        format=request.META.get(
                                            'CONTENT_TYPE',
                                            'application/json'))
        #print(request.user)
        self.update_application(request, deserialized)
        #self.update_in_place(request, bundle, deserialized)
        #print(deserialized)
        #print(request)

        if not self._meta.always_return_data:
            return http.HttpAccepted()
        else:
            # Invalidate prefetched_objects_cache for bundled object
            # because we might have changed a prefetched field
            bundle.obj._prefetched_objects_cache = {}
            bundle = self.full_dehydrate(bundle)
            bundle = self.alter_detail_data_to_serialize(request, bundle)
            return self.create_response(request,
                                        bundle,
                                        response_class=http.HttpAccepted)
Esempio n. 15
0
 def patch_list(self, request, **kwargs):
     request = convert_post_to_patch(request)
     deserialized = self.deserialize(
         request, request.body, format=request.META.get("CONTENT_TYPE", "application/json")
     )
     for data in deserialized["objects"]:
         data = self.alter_deserialized_detail_data(request, data)
         bundle = self.build_bundle(data=dict_strip_unicode_keys(data))
         bundle.request.user = request.user
         bundle.request.META["REMOTE_ADDR"] = request.META.get("REMOTE_ADDR", "0.0.0.0")
         bundle.request.META["HTTP_USER_AGENT"] = request.META.get("HTTP_USER_AGENT", "unknown")
         self.obj_create(bundle, request=request)
     response_data = {
         "points": self.dehydrate_points(bundle),
         "badges": self.dehydrate_badges(bundle),
         "scoring": self.dehydrate_scoring(bundle),
         "badging": self.dehydrate_badging(bundle),
         "metadata": self.dehydrate_metadata(bundle),
         "course_points": self.dehydrate_course_points(bundle),
     }
     response = HttpResponse(content=json.dumps(response_data), content_type="application/json; charset=utf-8")
     return response
    def patch_list(self, request, **kwargs):
        """
        Updates a collection in-place.

        The exact behavior of ``PATCH`` to a list resource is still the matter of
        some debate in REST circles, and the ``PATCH`` RFC isn't standard. So the
        behavior this method implements (described below) is something of a
        stab in the dark. It's mostly cribbed from GData, with a smattering
        of ActiveResource-isms and maybe even an original idea or two.

        The ``PATCH`` format is one that's similar to the response returned from
        a ``GET`` on a list resource::

            {
              "objects": [{object}, {object}, ...],
              "deleted_objects": ["URI", "URI", "URI", ...],
            }

        For each object in ``objects``:

            * If the dict does not have a ``resource_uri`` key then the item is
              considered "new" and is handled like a ``POST`` to the resource list.

            * If the dict has a ``resource_uri`` key and the ``resource_uri`` refers
              to an existing resource then the item is a update; it's treated
              like a ``PATCH`` to the corresponding resource detail.

            * If the dict has a ``resource_uri`` but the resource *doesn't* exist,
              then this is considered to be a create-via-``PUT``.

        Each entry in ``deleted_objects`` referes to a resource URI of an existing
        resource to be deleted; each is handled like a ``DELETE`` to the relevent
        resource.

        In any case:

            * If there's a resource URI it *must* refer to a resource of this
              type. It's an error to include a URI of a different resource.

            * ``PATCH`` is all or nothing. If a single sub-operation fails, the
              entire request will fail and all resources will be rolled back.

          * For ``PATCH`` to work, you **must** have ``put`` in your
            :ref:`detail-allowed-methods` setting.

          * To delete objects via ``deleted_objects`` in a ``PATCH`` request you
            **must** have ``delete`` in your :ref:`detail-allowed-methods`
            setting.

        Substitute appropriate names for ``objects`` and
        ``deleted_objects`` if ``Meta.collection_name`` is set to something
        other than ``objects`` (default).
        """
        request = convert_post_to_patch(request)
        deserialized = self.deserialize(request, request.body, format=request.META.get('CONTENT_TYPE', 'application/json'))

        collection_name = self._meta.collection_name
        deleted_collection_name = 'deleted_%s' % collection_name
        if collection_name not in deserialized:
            raise BadRequest("Invalid data sent: missing '%s'" % collection_name)

        if len(deserialized[collection_name]) and 'put' not in self._meta.detail_allowed_methods:
            raise ImmediateHttpResponse(response=http.HttpMethodNotAllowed())

        bulk_commands = []

        bundles_seen = []

        def index(bundle, command='index'):
            command = {command:{'_id':bundle.data["_id"]}}
            bulk_commands.append(command)
            command = bundle.obj
            bulk_commands.append(command)

        for data in deserialized[collection_name]:
            # If there's a resource_uri then this is either an
            # update-in-place or a create-via-PUT.
            if "resource_uri" in data:
                try:
                    uri = data.pop('resource_uri')

                    obj = self.get_via_uri(uri, request=request)

                    # The object does exist, so this is an update-in-place.
                    bundle = self.build_bundle(obj=obj['_source'], request=request)
                    bundle.data.update(data)
                    bundle = self.full_hydrate(bundle)

                    bulk_commands.append({'update':{'_id':bundle.data["_id"]}})
                    bulk_commands.append({'doc':bundle.obj})

                except (ObjectDoesNotExist, MultipleObjectsReturned):
                    # The object referenced by resource_uri doesn't exist,
                    # so this is a create-by-PUT equivalent.
                    data = self.alter_deserialized_detail_data(request, data)
                    bundle = self.build_bundle(data=dict_strip_unicode_keys(data), request=request)
                    #self.obj_create(bundle=bundle)
                    bundle = self.full_hydrate(bundle)
                    index(bundle)
            else:
                # There's no resource URI, so this is a create call just
                # like a POST to the list resource.
                data = self.alter_deserialized_detail_data(request, data)
                bundle = self.build_bundle(data=dict_strip_unicode_keys(data), request=request)
                #self.obj_create(bundle=bundle)
                bundle = self.full_hydrate(bundle)
                index(bundle)

            bundles_seen.append(bundle)

        deleted_collection = deserialized.get(deleted_collection_name, [])

        if deleted_collection:
            if 'delete' not in self._meta.detail_allowed_methods:
                raise ImmediateHttpResponse(response=http.HttpMethodNotAllowed())

            for uri in deleted_collection:
                obj = self.get_via_uri(uri, request=request)
                bundle = self.build_bundle(obj=obj['_source'], request=request)
                #self.obj_delete(bundle=bundle)
                command = {"delete":{'_id':bundle['pk']}}
                bulk_commands.append(command)

        if len(bulk_commands):
            try:
                result = self.client.bulk(bulk_commands, refresh=True,
                                          index=self._meta.index,
                                          doc_type=self._meta.doc_type)
            except Exception, exc:
                response = http.HttpBadRequest(str(exc), content_type="text/plain")
                raise ImmediateHttpResponse(response)
            else:
                if not self._meta.always_return_data:
                    return http.HttpAccepted(json.dumps(result))
                else:
                    to_be_serialized = {}
                    to_be_serialized['objects'] = [self.full_dehydrate(bundle, for_list=True) for bundle in bundles_seen]
                    to_be_serialized = self.alter_list_data_to_serialize(request, to_be_serialized)
                    return self.create_response(request, to_be_serialized, response_class=http.HttpAccepted)
Esempio n. 17
0
    def patch_list(self, request, **kwargs):
        """Override of the default to make the allowed methods map better.

        Mainly makes delete depend on delete (already happend).
        Makes creation depend on post, full update/create with URI depend
        on put and update existing depend on patch - which isn't a method at
        all.
        """
        request = convert_post_to_patch(request)
        if django.VERSION >= (1, 4):
            body = request.body
        else:
            body = request.raw_post_data
        deserialized = self.deserialize(request, body, format=request.META.get('CONTENT_TYPE', 'application/json'))

        collection_name = self._meta.collection_name
        deleted_collection_name = 'deleted_%s' % collection_name
        if collection_name not in deserialized:
            raise BadRequest("Invalid data sent: missing '%s'" % collection_name)

        #if len(deserialized[collection_name]) and 'put' not in self._meta.detail_allowed_methods:
        #    raise ImmediateHttpResponse(response=http.HttpMethodNotAllowed())

        bundles_seen = []

        for data in deserialized[collection_name]:
            # If there's a resource_uri then this is either an
            # update-in-place or a create-via-PUT.
            if "resource_uri" in data:
                uri = data.pop('resource_uri')

                try:
                    obj = self.get_via_uri(uri, request=request)

                    # The object does exist, so this is an update-in-place.
                    if 'patch' not in self._meta.detail_allowed_methods:
                        raise ImmediateHttpResponse(response=http.HttpMethodNotAllowed())
                    bundle = self.build_bundle(obj=obj, request=request)
                    bundle = self.full_dehydrate(bundle, for_list=True)
                    bundle = self.alter_detail_data_to_serialize(request, bundle)
                    self.update_in_place(request, bundle, data)
                except (ObjectDoesNotExist, MultipleObjectsReturned):
                    # The object referenced by resource_uri doesn't exist,
                    # so this is a create-by-PUT equivalent.
                    if 'put' not in self._meta.detail_allowed_methods:
                        raise ImmediateHttpResponse(response=http.HttpMethodNotAllowed())
                    data = self.alter_deserialized_detail_data(request, data)
                    bundle = self.build_bundle(data=dict_strip_unicode_keys(data), request=request)
                    self.obj_create(bundle=bundle)
            else:
                # There's no resource URI, so this is a create call just
                # like a POST to the list resource.
                if 'post' not in self._meta.detail_allowed_methods:
                    raise ImmediateHttpResponse(response=http.HttpMethodNotAllowed())

                data = self.alter_deserialized_detail_data(request, data)
                bundle = self.build_bundle(data=dict_strip_unicode_keys(data), request=request)
                self.obj_create(bundle=bundle)

            bundles_seen.append(bundle)

        deleted_collection = deserialized.get(deleted_collection_name, [])

        if deleted_collection:
            if 'delete' not in self._meta.detail_allowed_methods:
                raise ImmediateHttpResponse(response=http.HttpMethodNotAllowed())

            for uri in deleted_collection:
                obj = self.get_via_uri(uri, request=request)
                bundle = self.build_bundle(obj=obj, request=request)
                self.obj_delete(bundle=bundle)

        if not self._meta.always_return_data:
            return http.HttpAccepted()
        else:
            to_be_serialized = {}
            to_be_serialized['objects'] = [self.full_dehydrate(bundle, for_list=True) for bundle in bundles_seen]
            to_be_serialized = self.alter_list_data_to_serialize(request, to_be_serialized)
            return self.create_response(request, to_be_serialized, response_class=http.HttpAccepted)