【问题标题】:Tastypie return data from DELETE requests?从 DELETE 请求中返回数据?
【发布时间】:2014-06-22 07:52:21
【问题描述】:

我有一个简单的资源,我想执行 DELETE。成功后,我想获取已删除对象的 ID。根据文档,always_return_data - 指定所有 HTTP 方法(DELETE 除外)应返回数据的序列化形式。

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

问题: 无论如何要序列化数据以返回被删除的对象?

【问题讨论】:

    标签: django mongodb tastypie


    【解决方案1】:

    查看sourcedocumentation 的tastepie,看起来您需要覆盖ModelResourceMongoEngineResource inherits)的两个函数

    1. obj_delete 删除对象。

    2. delete-detail 在 DELETE 请求上调用并调用 obj_delete 然后返回 204 No Content404 Not Found

    我没有使用过美味的派,所以这一切都是从查看文档开始的,但这至少是一个起点。你需要对你的班级做这样的事情:

    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()
    

    【讨论】:

    • 当我只想删除与补丁请求相同的特定字段数据时该怎么办更新任何字段而不触及其他字段。我在 Mongonengine 中使用 Tastypie,所以我的模型中有一个 ListField,我可以使用补丁请求更新列表,但是我应该怎么做才能从 ListField 中删除任何项目。???以及当我的 MongoEngine 模型类中有多个 ListField 时该怎么办。
    【解决方案2】:

    您不需要返回已删除的对象。您可以只更新 obj_delete 中的 bundle.obj,然后将其返回到 delete_detail。 我正在使用自定义资源和中间件来运行 api,但如果你跳过元模型,它就很简单了。

    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()
    
    

    【讨论】:

      猜你喜欢
      • 2012-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-25
      • 1970-01-01
      • 2019-11-24
      • 1970-01-01
      • 2021-06-05
      相关资源
      最近更新 更多