has_permission()缺少1个必需的位置参数:“ view” [英] has_permission() missing 1 required positional argument: 'view'

查看:82
本文介绍了has_permission()缺少1个必需的位置参数:“ view”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用以下配置进行学习的项目:
Python 3.4.4
django == 1.9.1
djangorestframework == 3.3.3
OS( Windows 8.1)`



在项目中我有一个模型帖子,为此我创建了权限。py

  from rest_framework的导入权限


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:




 来自rest_framework导入权限,视图集
来自rest_framework.response import响应

来自posts.models从posts.permissions导入Post
从posts.serializers导入IsAuthorOfPost
导入PostSerializer


类PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.order_by('-created_at')
serializer_class = PostSerializer

def get_permissions(self):
,如果self.request.method在权限中。SAFE_METHODS:
返回(permissions.AllowAny(),)
返回(permissions.IsAuthenticated,IsAuthorOfPost(),)

def perform_create(self,serializer):
instance = serializer.save(author = self.request.user)
return super(PostViewSet,self).perform_create(serializer)


类AccountPostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.select_related('author')。all()
serializer_class = PostSerializer

def列表(self,request,account_username = None):
queryset = self.queryset.filter(author__username = account_username)
serializer = self.serializer_class(queryset,many = True)

返回响应(serializer.dat a)




serializers.py:




 从rest_framework导入序列化器

从authentication.serializers从posts.models导入AccountSerializer
导入Post


类PostSerializer(serializers.ModelSerializer):
author = AccountSerializer(read_only = True,required = False)

class Meta:
模型=发布
字段=('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()

返回例外+ ['作者']




urls.py




 来自django.conf.urls导入url,包括
来自django.contrib导入管理员
来自rest_f ramework.routers从rest_framework_nested导入DefaultRouter
从djangular.views导入Default $ r

从authentication.views导入IndexView
从authentication.views导入AccountViewSet,LoginView,LogoutView
从posts.views导入PostViewSet,AccountPostViewSet

router = routers.SimpleRouter()

router.register(r'accounts',AccountViewSet)
router.register(r'posts', PostViewSet)

account_router =路由器.NestedSimpleRouter(
路由器,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 /


错误




<$ / api / v1 / posts /
has_permission()处的p $ p> TypeError缺少1个必需的位置参数:'view'
请求方法:GET
请求URL: http:// localhost:8000 / api / v1 / posts /
Django版本:1.9.1
异常类型:TypeError
异常值:
has_permission()缺少1个必需的位置参数:'view'
异常位置:C:\Users\Devansh\Envs\19\lib\site-packages\rest_framework\views.py in check_permissions,第318行
Python可执行文件:C:\Users\Devansh\Envs\19\Scripts\python.exe
Python版本:3.4.4
Python路径:
['D :\\djangular-app',
'C:\\Windows\\SYSTEM32\\python34.zip',
'C:\\Users\ \Devansh\\Envs\\19\\DLLs',
'C:\\Users\\Devansh\\Envs\\19\\ \lib',
'C:\\U sers\\Devansh\\Envs\\19\\Scripts',
'c:\\python34\\Lib',
'c:\ \\python34\\DLLs',
'C:\\Users\\Devansh\\Envs\\19',
'C:\\ \Users\\Devansh\\Envs\\19\\lib\\site-packages']




跟踪




 跟踪(最近一次通话):
文件 C:\Users\Devansh\Envs\19\lib\site-packagesdjango\core\ \handlers\ba
,第174行,在get_response
response = self.process_exception_by_middleware(e,request)
File C:\Users\Devansh\Envs\19\ \lib\site-packages\django\core\handlers\ba
,第172行,位于get_response
response = response.render()
文件 C:\用户\ Devansh \ Envs \ 19 \库包django \模板\响应
第160行,渲染
self.content = self.rendered_content
文件 C:\Users\Devansh\Envs\19\lib\site-packages\rest_framework\response
第71行,在render_content
ret = renderer.render(self.data,media_type,context)中
File C:\Users\Devansh\Envs\19\lib\site-packages\ rest_framework\renderer
第676行,在渲染
上下文= self.get_context(data,accepted_media_type,renderer_context
文件 C:\Users\Devansh\Envs\19\ lib\site-packages\rest_framework\renderer
第618行,位于get_context
raw_data_post_form = self.get_raw_data_form(data,view,'POST',reques
File C:\用户\开发环境\ 19站点库\ REST框架\渲染器
第521行,如果不是self,则位于get_raw_data_form
中。show_form_for_method(视图,方法,请求,实例):
文件 C:\Users\Devansh\Envs\19\lib\site-packages\rest_framework\renderer
第417行,在show_form_for_method
视图中.check_permissions(request)
文件 C:\Users\Devansh\Envs\19\lib\site-packages\rest_framework\views.py
e 318,in check_permissions
(如果没有权限)。has_pe缓解(要求,自我):
TypeError:has_permission()缺少1个必需的位置参数:'view'


解决方案

您缺少权限的类实例化。IsAuthenticated

  def get_permissions(self):
如果self.request.method在权限中SAFE_METHODS:
return(permissions.AllowAny(),)
return(permissions.IsAuthenticated,IsAuthorOfPost(),)
#^^^

错误消息来自在类上的 IsAuthenticated 上调用实例方法。因此,请求映射到自身视图映射到<$然后缺少c $ c> request 和 view 本身。



更改 get_permissions()

  def get_permissions(self):
如果权限中的self.request.method.SAFE_METHODS:
返回(permissions.AllowAny(),)
返回(permissions.IsAuthenticated(),IsAuthorOfPost(),)
#^^

应该可以解决问题。



:您的 get_permissions()代码在确定授权中起着积极的作用。最好将此功能移入权限本身,以使代码更好地遵循单一职责原则。


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.

这篇关于has_permission()缺少1个必需的位置参数:“ view”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆