How to filter objects by user id with tastypie?
I have the following user resource:
class UserResource(ModelResource):
class Meta:
queryset = User.objects.all()
resource_name = 'user'
fields = ['username', 'first_name', 'last_name']
allowed_methods = ['get']
filtering = {
'username': ALL,
'id': ALL,
}
and the following model resource:
class GoalResource(ModelResource):
user = fields.ForeignKey(UserResource, 'user')
class Meta:
#authentication = BasicAuthentication()
#authorization = ReadOnlyAuthorization()
queryset = Goal.objects.all()
resource_name = 'goal'
filtering = {
'user': ALL_WITH_RELATIONS,
}
I want to be able to filter a target by user id, not username.
I can get a list of targets from specific usernames by doing a GET request:
http://localhost:8000/api/v1/goal/?user__username=test
But I want to be able to sort by user id:
http://localhost:8000/api/v1/goal/?user__id=1
How do I get the second part to work?
Also, what is the general procedure for accessing the current user ID via Javascript? I am using backbonejs and I want to make a post to all registered users. I thought about putting a hidden field on the page with the user id. Then fetching the value of the hidden field from the DOM, but I found it easy to use the Chrome developer tools to change the ID whenever I want. Of course, I will use authentication to verify that the registered user ID matches the ID that I am retrieving from the hidden field. But what's the acceptable way?
source to share
I'm not sure if what I'm suggesting here might work in your authorization. It works for me with ApiKeyAuthorization and Authorization.
I read this idea: http://django-tastypie.readthedocs.org/en/latest/cookbook.html [Section: Creating Resources for Each User]
My suggestion:
How about unauthorized authentication and authorization and overriding obj_create and apply_authorization. I am using this in my project and it works. In the code for the apply_authorization method, I just added an if check for the superuser, you can just return the object_list + filter without checking it (I do this, if not superuser, I return data related to user groups).
class GoalResource(ModelResource):
user = fields.ForeignKey(UserResource, 'user')
class Meta:
authentication = BasicAuthentication()
authorization = ReadOnlyAuthorization()
queryset = Goal.objects.all()
resource_name = 'goal'
filtering = {
'user': ALL_WITH_RELATIONS,
}
def obj_create(self, bundle, request=None, **kwargs):
return super(EnvironmentResource, self).obj_create(bundle, request, user=request.user)
def apply_authorization_limits(self, request, object_list):
if request.user.is_superuser:
return object_list.filter(user__id=request.GET.get('user__id',''))
Hope this is what you asked for and it helps. better with this!
source to share
Note. - apply_authorization_limits is deprecated.
An alternative way to filter by the current user is to override read_list in your authorization class. This is what I have. My class overrides DjangoAuthorization.
def read_list(self, object_list, bundle):
klass = self.base_checks(bundle.request, object_list.model)
if klass is False:
return []
# GET-style methods are always allowed.
# Filter by user
if not hasattr(bundle.request, 'user'):
return None
object_list = object_list.filter(user__id=bundle.request.user.id)
return object_list
source to share