Dev*_*nsh 8 python django django-rest-framework
我正在开发一个用于学习目的的项目,具有以下配置:Python 3.4.4 django == 1.9.1 djangorestframework == 3.3.3 OS(Windows 8.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'),
]
错误:
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 (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'
您缺少类实例化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()代码在决定授权时发挥了积极作用.最好将此功能转移到权限本身,以使代码更好地遵循单一责任原则.
| 归档时间: | 
 | 
| 查看次数: | 4085 次 | 
| 最近记录: |