In my current code, a user has a list of goals he has joined. I want an API endpoint to expose all of the user’s joined goals. I want to be able to post, put, and get to this API endpoint. It will get a list of the joined goals, add a goal to the joined goals list, or make an update to the joined goals list.
# Joined Goal Resource
class JoinedGoalResource(ModelResource):
user = fields.ForeignKey(UserResource, 'user')
joined_goals = fields.ManyToManyField(GoalResource, 'joined_goals', full=True)
class Meta:
authentication = Authentication()
authorization = Authorization()
queryset = UserProfile.objects.all()
resource_name = 'joined_goal'
allowed_methods = ['get', 'post', 'put']
filtering = {
'user': ALL_WITH_RELATIONS
}
The problem with the above code is that it uses UserProfile model as its queryset so if I do a post, get, or put on the API endpoint, it will effect the UserProfile rather than the user’s joined_goals.
Edit:
I have changed my code so that the joined resource overrides the obj_create method and just adds to the logged in user’s joined goal list. The problem is that the method requires me to return a bundle. How do I create the bundle to return? I am doing something like this:
goal_resource = GoalResource
goal_obj = goal_resource.obj_get(pk=1)
goal_bundle = goal_resource.build_bundle(obj=goal_obj, request=request)
return goal_bundle
But the obj_get doesn’t work when taking in an argument of pk=1
The solution can be quite simple.
You could implement a regular resource (forgetting about user ownership) and then follow the “Creating per-user resources” section of Tastypie cookbook to narrow the list returned by GET and ensure that the newly created objects are owned by the current user (POST).
With respect to PUT, you just need authorization class which ensures the user is only authorized to update his/her own goals. This is the trickiest part (but not hard), just make sure that the value of
userattribute of thegoalbundle is the same arequest.userwhen the method is PUT otherwise raise an exception and you’re done 🙂So with above you’d have following URIs:
and you could introduce (for GET):
by following Nested Resources section of the cookbook