Django 1.11 get()缺少1个必需的位置参数:“ pk”

时间:2019-01-24 11:27:25

标签: python django url django-rest-framework

我正在使用Django 1.11,并且路径参数有问题。 对于涉及路径参数的所有请求,我都会收到这样的错误。

Error:
TypeError at /posts/2
get() missing 1 required positional argument: 'pk'

urls.py
...
url(r'^posts',PostView.as_view()),
url(r'^posts/<int:pk>/',PostView.as_view()),
...

views.py
..
#-------- API for CRUD -----------------#
class PostView(APIView):
    permission_classes = (IsAuthenticated,)

    def get_object(self,pk,user_id):
        try:
            return Post.objects.get(pk=pk,user_id=user_id)
        except Post.DoesNotExist:
            raise Http404

    def get(self,request,pk):
        post = Post.objects.get(user=request.user.id)
        serializer = PostSerializer(post)
        return Response({"success":True,"data":serializer.data},status=status.HTTP_200_OK)

    def put(self, request, pk):
        post = self.get_object(pk,request.user.id)
        serializer = PostSerializer(post, data=request.data)
        if serializer.is_valid():
            serializer.save(user=request.user.id)
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def post(self,request):
        params = request.data
        params['user'] = request.user.id
        serializer = PostSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        saved_data = self.perform_create(serializer)
        post = PostSerializer(saved_data)
        return Response({"success":True, "message":"Post  Added Successfully","data":post.data}, status=status.HTTP_201_CREATED)

    def perform_create(self, serializer):
        return serializer.save()
...

网址示例:

GET : localhost:8000/posts/2

有人可以告诉我如何传递位置参数。

2 个答案:

答案 0 :(得分:1)

您的getpost签名仅接受selfrequest参数,而此处的签名应包括URL的pk参数。由于您为URL 没有 pk定义了相同的视图,因此应将这些参数设为 optional (因此请添加默认值,以防丢失)。喜欢:

class PostView(APIView):
    permission_classes = (IsAuthenticated,)

    def get_object(self,pk,user_id):
        # ...
        pass

    def get(self,request, pk=None):
        # ...
        pass

    def put(self, request, pk=None):
        # ...
        pass

    def post(self,request, pk=None):
        # ...
        pass

另一种方法是在URL中为kwargs提供缺少的参数,例如:

path(r'posts',PostView.as_view(), kwargs={'pk': None}),
path(r'posts/<int:pk>/',PostView.as_view())

或对于之前的安装,您需要将其定义为正则表达式:

url(r'^posts/$',PostView.as_view(), kwargs={'pk': None}),
url(r'^posts/(?P<pk>[0-9]+)/',PostView.as_view())

答案 1 :(得分:1)

在以上代码中,您将user_idpk用作请求方法和视图方法get_object中的位置参数。 pkuser_id在整个视图中可用。您可以像self.kwargs.get('pk')self.request.user.pk这样使用它们。 请检查下面的代码以了解实施细节。

class PostView(APIView):
    permission_classes = (IsAuthenticated,)

    def get_object(self):
        pk = self.kwargs.get('pk')
        user_id = self.request.id
        try:
           return Post.objects.get(pk=pk,user_id=user_id)
        except Post.DoesNotExist:
           raise Http404

    def get(self,request, *args, **kwargs):
        # ...
        pass

    def put(self, request, *args, **kwargs):
        # ...
        pass

    def post(self,request, *args, **kwargs):
        # ...
        pass