Django Rest Framework:POST的一个URL,同一个APIView上的一个GET URL

时间:2018-05-01 20:46:53

标签: python django django-rest-framework

我目前正在撰写POST请求以创建A记录:

client.post(url, {'name' : 'foo', 'another_field' : 2})

在服务器端,在视图上,我有:

class AQuery(generics.GenericAPIView):
    queryset = A.objects.all()
    serializer_class = ASerializer

    def get(self, request, param1, param2, format=None):
        ... # do some special query based off of param1 and 2.

    def post(self, request, format=None):
        serializer = self.get_serializer(data=request.data, many=False) 
        if serializer.is_valid():
            serializer.save()
            return Response(...)
        return Response(...)

如您所见,我希望在网址中捕获param1param2,因此在urls.py

urlpatterns = [
    # for GET
    path('A/<str:param1>/<path:param2>', views.AQuery.as_view(), name='A query GET')
    # for POST
    path('A', views.AQuery.as_view(), name='A query POST')
    ...
]

显然,我可以将param1param2添加到post函数def,但它们只是那里,没有任何意义。好像我的代码味道不好。

我将如何实现这样的操作,并明确禁止客户端向A/param1/param2发出POST请求,并明确禁止客户端向A/发出GET请求?

我尝试了什么

我尝试将视图转换为viewsets.ModelViewSet,并添加了以下内容:

a_get_query = AQuery.as_view({'get':'get'})
a_post_query = AQuery.as_view({'post':'post'})

和我的urls.py

urlpatterns = [
        # for GET
        path('A/<str:param1>/<path:param2>', views.a_get_query, name='A query GET')
        # for POST
        path('A', views.a_post_query, name='A query POST')
        ...
    ]

但是我收到以下错误:

  

TypeError:在ViewSet上调用actions时必须提供.as_view()参数。例如.as_view({'get': 'list'})

我不确定它在哪里发生。

1 个答案:

答案 0 :(得分:2)

这种方法对我有用。然而,我不得不进行一些小改动:

1)我必须将函数的名称从getpost更改为do_getdo_post。当函数的名称与HTTP方法本身相同时,Django似乎做了一些特别的事情。

2)我在as_view()

中直接调用urls.py

这样做之后:

urlpatterns = [
        # for GET
        path('A/<str:param1>/<path:param2>', views.AQuery.as_view({'get':'do_get'}), name='A query GET')
        # for POST
        path('A', views.AQuery.as_view({'post':'do_post'}), name='A query POST')
        ...
    ]

结果:

GET   A/param1/param2  -> 200 OK
GET   A/               -> 405 Method Not Allowed

POST  A/param1/param2  -> 405 Method Not Allowed
POST  A/               -> 200 OK