出于某种原因,我在发送 POST 请求时遇到了一些奇怪的问题。
这是我的 URL 设置:
http://host/api/user/1/edit/
http://host/api/address/search/
其中/api/是API-Root,user是模型,1是用户ID,edit和search是自定义的功能。
这是在 views.py 中:
class UserViewSet(viewsets.ModelViewSet):
...
def post(self, request, pk, *args, **kwargs):
... (processing)
@detail_route(methods=['post'])
def edit(self, request, pk, *args, **kwargs):
... (processing)
class AddressViewSet(viewsets.ModelViewSet):
...
def post(self, request, *args, **kwargs):
... (processing)
@detail_route(methods=['post'])
def search(self, request, *args, **kwargs):
... (processing)
这是在 urls.py 中:
router = DefaultRouter()
router.register(r'user', views.UserViewSet)
router.register(r'address', views.AddressViewSet)
urlpatterns = [
url(r'^', include(router.urls)),
url(r'^authentication/', include('rest_framework.urls', namespace='rest_framework'))
]
我遇到的奇怪的事情是:
如果我正在使用 httpie 并像这样发送一个 POST 编辑请求:
http POST http://host/api/user/1/edit/ name="john" address="google.com"
那么 def post 中的内容将永远不会被执行。如果我让浏览器发送一个 POST 请求,这也是一样的。
但是,如果我通过以下方式发送 POST 搜索请求:
http POST http://host/api/address/search/ name="john"
那么在这种情况下,def search 中的内容永远不会被执行,而只有 def post 中的内容会被执行。
我能看到的唯一区别是对于 edit,有一个额外的 pk(本例中 1 的值),而有没有用于“搜索”的 pk。
有人知道为什么会这样吗?这让我很困惑
请您参考如下方法:
在 ViewSet 中定义 post() 不会做任何事情,这是针对 APIView 派生类的。如果您想覆盖 ViewSet 中的默认对象创建,您可以选择
def create(self, request, *args, **kwargs):
... do stuff ...
甚至更好
def perform_create(self, serializer):
... do stuff ...
serializer.save()
关于地址,需要使用list_route装饰器,而不是detail_route。 detail_route 用于对单个对象进行操作,而 list_route 用于列表。所以/address/search/应该是 list route 而/address/1/search/应该是 detail_route。请注意,我认为您在 post() 中的代码在任何一种情况下都不会运行。
这是一篇相关的文档 http://www.django-rest-framework.org/api-guide/viewsets/#marking-extra-actions-for-routing
