2016-05-08 15 views
1

i an einem Projekt arbeitet für das Lernen Zweck mit folgenden config: Python 3.4.4 django == 1.9.1 djangorestframework == 3.3.3 OS (Windows 8.1) `has_permission() fehlt 1 erforderlich Positions Argument: 'view'

Im Projekt mit i ein Modell Beitrag für die ich geschaffen habe 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/

Fehler:

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' 

Antwort

3

Sie sind eine Klasse Instanziierung für permissions.IsAuthenticated fehlt:

def get_permissions(self): 
    if self.request.method in permissions.SAFE_METHODS: 
     return (permissions.AllowAny(),) 
    return (permissions.IsAuthenticated, IsAuthorOfPost(),) 
#          ^^^ 

Die Fehlermeldung kommt vom Aufruf der Instanzmethode auf IsAuthenticated für die Klasse. Also request wird auf self, view zu request und view selbst gemappt wird dann fehlt.

Ändern get_permissions() zu

def get_permissions(self): 
    if self.request.method in permissions.SAFE_METHODS: 
     return (permissions.AllowAny(),) 
    return (permissions.IsAuthenticated(), IsAuthorOfPost(),) 
#          ^^ 

sollte das Problem lösen.

Als eine Randnotiz: Ihr get_permissions() Code spielt eine aktive Rolle bei der Entscheidung über die Autorisierung. Es wäre besser, diese Funktionalität in die Berechtigungen selbst zu verschieben, damit der Code besser dem Prinzip der einfachen Verantwortlichkeit folgt.

+0

Schöne Antwort, könnten Sie diese Zeile, die Sie geschrieben haben, erklären? "Es wäre besser, diese Funktionalität in die Berechtigungen selbst zu verschieben, damit der Code besser dem Prinzip der einheitlichen Verantwortung folgt." –

+0

@ShubhamAggarwal 'wenn self.request.method in permissions.SAFE_METHODS' ist eine Berechtigungsprüfung. "* Wenn Sie diese Methoden verwenden, dann ... *". Hier überschreibt die Ansicht die Berechtigungsprüfung, indem basierend auf der Anforderungsmethode verschiedene Berechtigungen verwendet werden. Das bedeutet, dass Sie an zwei Stellen Berechtigungsprüfungen haben (die Berechtigungen selbst und die Ansicht). ['IsAuthenticatedOrReadOnly'] (https: // github.com/tomchristie/django-rest-framework/blob/dbbf79be6496c66070fcf24d17b9c19e06925bd4/rest_framework/berechtigungen.py # L59) existiert genau aus diesem Grund. – dhke

+0

danke @dhke, und Sie haben gute Vorschläge zum Verschieben von Berechtigungen in permissions.py bereitgestellt – Devansh

Verwandte Themen