2016-05-08 5 views
1

я работаю над проектом для учебных целей с следующей конфигурацией: Python 3.4.4 Джанго == 1.9.1 djangorestframework == 3.3.3 OS (Windows, 8,1) `has_permission() отсутствует 1 необходимые позиционная аргумент: 'вид'

В проекте я имея модель Post для этого я создал 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/

Ошибка:

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' 

ответ

3

У вас не хватает экземпляров класса для permissions.IsAuthenticated:

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

Сообщение об ошибке происходит от вызова метода экземпляра на IsAuthenticated класса. Таким образом, request сопоставляется с self, view - request и view сам отсутствует.

Изменение get_permissions() к

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

должны решить эту проблему.

В качестве примечания стороны: Ваш код get_permissions() принимает активное участие в принятии решения. Было бы лучше перенести эту функциональность в сами разрешения, чтобы код лучше соответствовал принципу единой ответственности.

+0

Хороший ответ. Не могли бы вы объяснить эту строку, которую вы написали? «Было бы лучше перенести эту функциональность в сами разрешения, чтобы код лучше соответствовал принципу единой ответственности». –

+0

@ShubhamAggarwal 'if self.request.method в permissions.SAFE_METHODS' является авторизацией. "* При использовании этих методов, тогда ... *". Здесь представление отменяет проверку разрешений с использованием разных разрешений на основе метода запроса. Это означает, что у вас есть проверки разрешений в двух местах (сами разрешения и представление). [ 'IsAuthenticatedOrReadOnly'] (https: // GitHub.com/tomchristie/django-rest-framework/blob/dbbf79be6496c66070fcf24d17b9c19e06925bd4/rest_framework/permissions.py # L59) существует именно по этой причине. – dhke

+0

благодарит @dhke, и вы обеспечили хорошую привязку для перемещения разрешений на permissions.py – Devansh

Смежные вопросы