Domanda

I have a simple resource that I would like perform a DELETE. On success I would like to get the ID of the object that was deleted. As per the docs, always_return_data - Specifies all HTTP methods (except DELETE) should return a serialized form of the data.

http://django-tastypie.readthedocs.org/en/latest/resources.html#always-return-data

class SimpleResource(resources.MongoEngineResource):
    class Meta:
        queryset = Simple.objects.all()
        resource_name = 'simple'
        allowed_methods = ('get', 'put', 'post', 'delete', 'patch')
        always_return_data = True

Question: Is there anyway to serialize data to return the object that was deleted?

È stato utile?

Soluzione

Looking at the source and documentation for tastypie, it looks like you'll need to override two functions of ModelResource (which MongoEngineResource inherits):

  1. obj_delete which deletes the object.

  2. delete-detail which is called on a DELETE request and calls obj_delete then returns a 204 No Content or 404 Not Found

I haven't worked with tastypie so this is all from looking at the documentation, but it's at least a starting point. You'll need to do something like this to your class:

class SimpleResource(resources.MongoEngineResource):
    class Meta:
        queryset = Simple.objects.all()
        resource_name = 'simple'
        allowed_methods = ('get', 'put', 'post', 'delete', 'patch')
        always_return_data = True


    def obj_delete(self, bundle, **kwargs):
        try:
            # get an instance of the bundle.obj that will be deleted
            deleted_obj = self.obj_get(bundle=bundle, **kwargs)
        except ObjectDoesNotExist:
            raise NotFound("A model instance matching the provided arguments could not be found.")
        # call the delete, deleting the obj from the database
        super(MongoEngineResource, self).obj_delete(bundle, **kwargs)
        return deleted_obj


    def delete_detail(self, request, **kwargs):
        bundle = Bundle(request=request)

        try:
            # call our obj_delete, storing the deleted_obj we returned
            deleted_obj = self.obj_delete(bundle=bundle, **self.remove_api_resource_names(kwargs))
            # build a new bundle with the deleted obj and return it in a response
            deleted_bundle = self.build_bundle(obj=deleted_obj, request=request)
            deleted_bundle = self.full_dehydrate(deleted_bundle)
            deleted_bundle = self.alter_detail_data_to_serialize(request, deleted_bundle)
            return self.create_response(request, deleted_bundle, response_class=http.HttpNoContent)
        except NotFound:
            return http.HttpNotFound()

Altri suggerimenti

you do not need to return the deleted object. You can just update the bundle.obj in obj_delete and then return it to the delete_detail. I am using custom resources and a middleware to run the api, but if you skip on the meta-model thingy it is pretty straight forward.

def obj_delete(self,bundle, **kwargs):
    self.load_user_obj(bundle.request)
    l_instanceId = kwargs['pk']
    try:
        #load the instance
        self.m_objMetaModel.load(l_instanceId,True)

        #do the manipulation on it
        self.m_objMetaModel.REST_IMPL.delete()

        #get an instance back. In my case in the delete I
        #am creating a virtual instance- just an object that 
        #fits the other parts of the api
        bundle.obj = self.m_objMetaModel.instance

        #load the bundle manually
        self.m_objMetaModel.REST_IMPL.reload_data(bundle.obj,bundle.data)

        return bundle
    except Exception as e:
        print(e)
def delete_detail(self, request, **kwargs):
    bundle = Bundle(request=request)

    try:
        # perform the operation returning the recreated bundle
        deleted_bundle = self.obj_delete(bundle=bundle,
                                **self.remove_api_resource_names(kwargs))

        # keep the meta configuration, just to avoid surprises later
        if not self._meta.always_return_data:
            return http.HttpNoContent()
        else:
            #update the bundle, you can skip on the dehydrate if you 
            #are loading the bundle data manually
            deleted_bundle = self.full_dehydrate(deleted_bundle)
            deleted_bundle = self.alter_detail_data_to_serialize(request, 
                                                               deleted_bundle)
            return self.create_response(request, deleted_bundle)
    except NotFound:
            return http.HttpNotFound()

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top