dan_boy
dan_boy

Reputation: 2019

How to resolve error "object_permission() takes 3 positional arguments but 4 were given"?

I am trying to implement an object-level permission. When I run my code, I get an error message saying that I am using too many positional arguments.

TypeError: has_object_permission() takes 3 positional arguments but 4 were given

However, when I check the documentation for the Django Rest framework, four arguments are also used.

class PostOwnerPermssion(permissions.BasePermission):
    """
    Check if authenticated user is  story author
    """
    def has_object_permission(self,request,obj,**kwargs):
        if request.user.id == story.author:
            return True
        return False

Im happy for any clarification.

Thank you.

Upvotes: 2

Views: 2000

Answers (2)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477230

However, when I check the documentation for the Django Rest framework, four arguments are also used.

class PostOwnerPermssion(permissions.BasePermission):
    """
    Check if authenticated user is  story author
    """
    def has_object_permission(self,request,obj,**kwargs):
        if request.user.id == story.author:
            return True
        return False

No, **kwargs matches with an arbitrary number of named parameters, so you can call this with my_post_owner_permssion.has_object_permission(request, some_obj, foo=bar, qux=bar2)` but not with positional parameters (parameters without a name).

You can implement one (or both) of the following methods:

  1. .has_permission(self, request, view); and
  2. .has_object_permission(self, request, view, obj)

What is missing in your case, is the view parameter, so you can rewrite this to:

class PostOwnerPermssion(permissions.BasePermission):
    """
    Check if authenticated user is  story author
    """
    def has_object_permission(self, request, view, obj):
        return request.user.id == obj.author_id

Upvotes: 4

Lane
Lane

Reputation: 695

There are three positional arguments in (self,request,obj,**kwargs): self,request,obj.

You can call it like obj.has_object_permission(foo, bar). Note that **kwargs is named argument, so you have to call it with name such as obj.has_object_permission(foo, bar, named_arg='something').

Upvotes: 2

Related Questions