简体   繁体   中英

Django tastypie 'POST' with overriden save() on model

I'm using tastypie and oauth2 with overidden save() on my model, trying to POST a new object using curl --dump-header - -H "Authorization: OAuth MYTOKEN" -H "Content-Type: application/json" ":21.21, "longitude":12.32}' http://localhost:8000/api/v1/location/

My goal is to create a new object using the resource but also save the object with User credentials.

Now I'm getting this error: {"error_message": "save() takes exactly 2 arguments (1 given)"...}

My overriden save() in my Location Model:

def save(self, request):
    if self.latitude and self.longitude:
        self.gps_location = Point(self.latitude, self.longitude)
    if not self.id:
        self.created = datetime.datetime.now()
    self.updated = datetime.datetime.now()
    if hasattr(request,'user'):
        self.created_by = request.user
    else:
        self.created_by = None
    super(Location, self).save()

My resource:

class LocationResource(ModelResource):
    class Meta:
        fields = ['created', 'updated', 'latitude', 'longitude',]
        queryset = Location.objects.all()
        resource_name = 'location'
        allowed_methods = ['post', 'get', 'put']
        filtering = {'type':ALL_WITH_RELATIONS}
        authorization = DjangoAuthorization()
        authentication = OAuth20Authentication()
        include_resource_uri = False

    def create_obj(self, bundle, **kwargs):
        try:
            old_save = bundle.obj.save
            bundle.obj.save = partial(old_save, user=bundle.request.user)
            return super(LocationResource, self).save(bundle)
        finally:
            bundle.obj.save = old_save
        bundle.obj.created_by = bundle.request.user
        #return super(LocationResource, self).obj_create(bundle, user=bundle.request.user)

    def hydrate(self, bundle):
        bundle.obj.user = bundle.request.user
        return bundle

    def apply_authorization_limits(self, request, object_list):
        return object_list.filter(user=request.user)

I found this post and tried both suggestions for solution (as you can see above) which did not help.

How can I send a request object to the overidden save() on my model or solve this in another way?

Overridig hydrate() on created_by solved this for me. My solution for this:

Model ( request and created_by assignment removed from save() ):

def save(self):
    if self.latitude and self.longitude:
        self.gps_location = Point(self.latitude, self.longitude)
    if not self.id:
        self.created = datetime.datetime.now()
    self.updated = datetime.datetime.now()
    super(Location, self).save()

Resource (see comments for changes):

class LocationResource(ModelResource):
    class Meta:
        # stays the same

    def create_obj(self, bundle, **kwargs):
        # with this solution- no need to override create_obj

    def hydrate(self, bundle):
        bundle.obj.created_by = bundle.request.user # changed from bundle.obj.user to bundle.obj.created by - my mistake
        return bundle

    def apply_authorization_limits(self, request, object_list):
        # stays the same

Now, when I curl as mentioned in question I get CREATED response and a new node is created of course.

Thanks

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM