Skip to main content
 首页 » 编程设计

python之Django REST Framework 奇怪的结果

2024年08月23日35zhoujg

出于某种原因,我在发送 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