如何在django美味馅饼中编写自定义obj_create和obj_update

时间:2015-09-16 05:35:02

标签: jquery django tastypie put

我试图在Django美味馅饼中覆盖obj_create和obj_update

class HomeTasksResource(ModelResource):
    class Meta:
        queryset = HomeTasks.objects.filter(is_deleted = False)
        resource_name = 'tasks'
        authorization = Authorization()
        authentication = MyAuthentication()
        excludes = [ 'datetime']
        allowed_methods = ['get','post','put','patch']
        serializer = urlencodeSerializer()
        always_return_data = True
    def obj_update(self, bundle, **kwargs):        
        taskForm = HomeTasksForm(bundle.data,instance = bundle.obj)                 
        if taskForm.is_valid():  

            messages.success(bundle.request,"The task is updated successfully")            
            returnData =  super(HomeTasksResource, self).obj_update(bundle,user = bundle.request.user,id = bundle.obj.id)

            return returnData 

    def obj_create(self, bundle, **kwargs): 

        taskForm = HomeTasksForm(bundle.data)
        if taskForm.is_valid() and bundle.obj is None:    
            messages.success(bundle.request,"The task is successfully added")            
            returnData =  super(HomeTasksResource, self).obj_create(bundle,user = bundle.request.user)                

            return returnData 

以上是有效的,但由于某些奇怪的原因,对于每次更新/放置调用,也会调用" create。"即放置两个功能都在运行。我究竟做错了什么 ? 我使用的是jquery和最新版本的tastypie。

1 个答案:

答案 0 :(得分:2)

tastypie调用put_detail的默认obj_update视图,但如果找不到该对象或无法找出要更新的对象,则会回退到obj_create。因此,对于每个新的条目,将调用obj_updateobj_create。但是,对于现有条目,理想情况下只应调用obj_update

def put_detail(self, request, **kwargs):
    """
    Either updates an existing resource or creates a new one with the
    provided data.

    Calls ``obj_update`` with the provided data first, but falls back to
    ``obj_create`` if the object does not already exist.

    If a new resource is created, return ``HttpCreated`` (201 Created).
    If ``Meta.always_return_data = True``, there will be a populated body
    of serialized data.

    If an existing resource is modified and
    ``Meta.always_return_data = False`` (default), return ``HttpNoContent``
    (204 No Content).
    If an existing resource is modified and
    ``Meta.always_return_data = True``, return ``HttpAccepted`` (200
    OK).
    """
    deserialized = self.deserialize(request, request.body, format=request.META.get('CONTENT_TYPE', 'application/json'))
    deserialized = self.alter_deserialized_detail_data(request, deserialized)
    bundle = self.build_bundle(data=dict_strip_unicode_keys(deserialized), request=request)

    try:
        updated_bundle = self.obj_update(bundle=bundle, **self.remove_api_resource_names(kwargs))

        if not self._meta.always_return_data:
            return http.HttpNoContent()
        else:
            updated_bundle = self.full_dehydrate(updated_bundle)
            updated_bundle = self.alter_detail_data_to_serialize(request, updated_bundle)
            return self.create_response(request, updated_bundle)
    except (NotFound, MultipleObjectsReturned):
        updated_bundle = self.obj_create(bundle=bundle, **self.remove_api_resource_names(kwargs))
        location = self.get_resource_uri(updated_bundle)

        if not self._meta.always_return_data:
            return http.HttpCreated(location=location)
        else:
            updated_bundle = self.full_dehydrate(updated_bundle)
            updated_bundle = self.alter_detail_data_to_serialize(request, updated_bundle)
            return self.create_response(request, updated_bundle, response_class=http.HttpCreated, location=location)