我正在使用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
有人可以告诉我如何传递位置参数。
答案 0 :(得分:1)
您的get
和post
签名仅接受self
和request
参数,而此处的签名应包括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())
或对于django-2.0之前的安装,您需要将其定义为正则表达式:
url(r'^posts/$',PostView.as_view(), kwargs={'pk': None}),
url(r'^posts/(?P<pk>[0-9]+)/',PostView.as_view())
答案 1 :(得分:1)
在以上代码中,您将user_id
,pk
用作请求方法和视图方法get_object
中的位置参数。 pk
和user_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