I am using a PATCH request in tastypie to update a field in my model but when this PATCH goes through I am trying to append the data that is already in the database rather than replacing the value entirely.
Example: In a blog post, a user flags a post as inappropriate. You want to get this user's UserID and append it to a field, flaggedUserID. flaggedUserID will contain this user's ID along with anyone else who has flagged the post previously.
Where I'm struggling is in finding a hook in tastypie through which I can access the query BEFORE the value is copied from the request into the data from the query. I tried the "alter_deserialized_detail_data(self, request, data)" hook but the value has already been replaced in the data parameter that is passed to this function.
Anyone have any suggestions?
After reading through the source code of tastypie this is the solution I came to:
The copying of data from the request to the query seems to be happening in the "update_in_place" function. By overriding this function in the following way I was able to accomplish the results I was looking for:
def update_in_place(self, request, original_bundle, new_data):
"""
Update the object in original_bundle in-place using new_data.
"""
"""Right here I am checking if the parameter flaggedUserID is in the
request (PATCH saves request data to request.body). If this is false then
copy the new data into the query, otherwise jump to
alter_deserialized_detail_data where I am handling the appending of the data
from the request. """
if 'flaggedUserID' not in request.body:
original_bundle.data.update(**dict_strip_unicode_keys(new_data))
# Now we've got a bundle with the new data sitting in it and we're
# we're basically in the same spot as a PUT request. SO the rest of this
# function is cribbed from put_detail.
self.alter_deserialized_detail_data(request, original_bundle.data)
kwargs = {
self._meta.detail_uri_name: self.get_bundle_detail_data(original_bundle),
'request': request,
}
return self.obj_update(bundle=original_bundle, **kwargs)
Depending on the objective I would probably recommend cleaning this up a little bit more. I just wanted to show this code in its most basic form without having to post multiple functions and start confusing people.