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?

+3


source to share


2 answers


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!

+4


source


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

      

+1


source







All Articles