i am working on a project for learning purpose with following config: Python 3.4.4 django==1.9.1 djangorestframework==3.3.3 OS (Windows 8.1)`
In project i having a model Post for that i have created permissions.py
from rest_framework import permissions
class IsAuthorOfPost(permissions.BasePermission):
def has_permission(self, request, view):
return True
def has_object_permission(self, request, view, post):
if request.user:
return post.author == request.user
return False
views.py:
from rest_framework import permissions, viewsets
from rest_framework.response import Response
from posts.models import Post
from posts.permissions import IsAuthorOfPost
from posts.serializers import PostSerializer
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.order_by('-created_at')
serializer_class = PostSerializer
def get_permissions(self):
if self.request.method in permissions.SAFE_METHODS:
return (permissions.AllowAny(),)
return (permissions.IsAuthenticated, IsAuthorOfPost(),)
def perform_create(self, serializer):
instance = serializer.save(author=self.request.user)
return super(PostViewSet, self).perform_create(serializer)
class AccountPostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.select_related('author').all()
serializer_class = PostSerializer
def list(self, request, account_username=None):
queryset = self.queryset.filter(author__username=account_username)
serializer = self.serializer_class(queryset, many=True)
return Response(serializer.data)
serializers.py:
from rest_framework import serializers
from authentication.serializers import AccountSerializer
from posts.models import Post
class PostSerializer(serializers.ModelSerializer):
author = AccountSerializer(read_only=True, required=False)
class Meta:
model = Post
fields = ('id', 'author', 'content', 'created_at', 'updated_at')
read_only_fields = ('id', 'created_at', 'updated_at')
def get_validation_exclusions(self, *args, **kwargs):
exclusions = super(PostSerializer, self).get_validation_exclusions()
return exclusions + ['author']
urls.py
from django.conf.urls import url, include
from django.contrib import admin
from rest_framework.routers import DefaultRouter
from rest_framework_nested import routers
from djangular.views import IndexView
from authentication.views import AccountViewSet, LoginView, LogoutView
from posts.views import PostViewSet, AccountPostViewSet
router = routers.SimpleRouter()
router.register(r'accounts', AccountViewSet)
router.register(r'posts', PostViewSet)
account_router = routers.NestedSimpleRouter(
router, r'accounts', lookup='account'
)
account_router.register(r'posts', AccountPostViewSet)
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api/v1/', include(router.urls)),
url(r'^api/v1/', include(account_router.urls)),
url(r'^api/v1/auth/login/$', LoginView.as_view(), name='login'),
url(r'^api/v1/auth/logout/$', LogoutView.as_view(), name='logout'),
url('^.*$', IndexView.as_view(), name='index'),
]
localhost:8000/api/v1/posts/
Error:
TypeError at /api/v1/posts/
has_permission() missing 1 required positional argument: 'view'
Request Method: GET
Request URL: http://localhost:8000/api/v1/posts/
Django Version: 1.9.1
Exception Type: TypeError
Exception Value:
has_permission() missing 1 required positional argument: 'view'
Exception Location: C:\Users\Devansh\Envs\19\lib\site-packages\rest_framework\views.py in check_permissions, line 318
Python Executable: C:\Users\Devansh\Envs\19\Scripts\python.exe
Python Version: 3.4.4
Python Path:
['D:\\djangular-app',
'C:\\Windows\\SYSTEM32\\python34.zip',
'C:\\Users\\Devansh\\Envs\\19\\DLLs',
'C:\\Users\\Devansh\\Envs\\19\\lib',
'C:\\Users\\Devansh\\Envs\\19\\Scripts',
'c:\\python34\\Lib',
'c:\\python34\\DLLs',
'C:\\Users\\Devansh\\Envs\\19',
'C:\\Users\\Devansh\\Envs\\19\\lib\\site-packages']
Traceback
Traceback (most recent call last):
File "C:\Users\Devansh\Envs\19\lib\site-packages\django\core\handlers\ba
, line 174, in get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\Devansh\Envs\19\lib\site-packages\django\core\handlers\ba
, line 172, in get_response
response = response.render()
File "C:\Users\Devansh\Envs\19\lib\site-packages\django\template\respons
line 160, in render
self.content = self.rendered_content
File "C:\Users\Devansh\Envs\19\lib\site-packages\rest_framework\response
line 71, in rendered_content
ret = renderer.render(self.data, media_type, context)
File "C:\Users\Devansh\Envs\19\lib\site-packages\rest_framework\renderer
line 676, in render
context = self.get_context(data, accepted_media_type, renderer_context
File "C:\Users\Devansh\Envs\19\lib\site-packages\rest_framework\renderer
line 618, in get_context
raw_data_post_form = self.get_raw_data_form(data, view, 'POST', reques
File "C:\Users\Devansh\Envs\19\lib\site-packages\rest_framework\renderer
line 521, in get_raw_data_form
if not self.show_form_for_method(view, method, request, instance):
File "C:\Users\Devansh\Envs\19\lib\site-packages\rest_framework\renderer
line 417, in show_form_for_method
view.check_permissions(request)
File "C:\Users\Devansh\Envs\19\lib\site-packages\rest_framework\views.py
e 318, in check_permissions
if not permission.has_permission(request, self):
TypeError: has_permission() missing 1 required positional argument: 'view'
You are missing a class instantiation for permissions.IsAuthenticated
:
def get_permissions(self):
if self.request.method in permissions.SAFE_METHODS:
return (permissions.AllowAny(),)
return (permissions.IsAuthenticated, IsAuthorOfPost(),)
# ^^^
The error message comes from calling the instance method on IsAuthenticated
on the class. Thus request
gets mapped to self
, view
to request
and view
itself is then missing.
Changing get_permissions()
to
def get_permissions(self):
if self.request.method in permissions.SAFE_METHODS:
return (permissions.AllowAny(),)
return (permissions.IsAuthenticated(), IsAuthorOfPost(),)
# ^^
should solve the problem.
As a side note: Your get_permissions()
code takes an active role in deciding authorization. It would be better to move this functionality into the permissions themselves to make the code better follow the single responsibility principle.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With