Python Django REST框架奇怪的结果
出于某种原因,我在发送Python Django REST框架奇怪的结果,python,django,django-rest-framework,Python,Django,Django Rest Framework,出于某种原因,我在发送POST请求时遇到了一些奇怪的问题 这是我的URL设置: http://host/api/user/1/edit/ http://host/api/address/search/ 其中,/api/是api根,user是模型,1是用户ID,edit和search是自定义函数 这是在views.py中: class UserViewSet(viewsets.ModelViewSet): ... def post(self, request, pk, *arg
POST
请求时遇到了一些奇怪的问题
这是我的URL设置:
http://host/api/user/1/edit/
http://host/api/address/search/
其中,/api/
是api根,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)
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'))
]
这在url.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)
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"
在这种情况下,defsearch
中的内容将永远不会执行,而只有defspost
中的内容才会执行
我能看到的唯一区别是,对于edit
,有一个额外的pk
(本例中的值为1
),而“搜索”没有pk
有人知道为什么会这样吗?在视图集中定义post()并没有任何作用,这是针对APIView派生类的,这对我来说真的很困惑。如果要覆盖视图集中的默认对象创建,可以
def create(self, request, *args, **kwargs):
... do stuff ...
def创建(self、request、*args、**kwargs):
... 做些事情。。。
甚至更好
def perform_create(self, serializer):
... do stuff ...
serializer.save()
def执行_创建(自、序列化程序):
... 做些事情。。。
serializer.save()
至于地址,您需要使用列表路由装饰器而不是详细路由。细节路径用于对单个对象进行操作,列表路径用于列表。所以/address/search/应该是列表路线,/address/1/search/应该是详细路线。请注意,我认为post()中的代码在这两种情况下都不会运行
下面是一段相关的文档当向rest框架提交post请求时,请求被映射到视图集上的方法,而Django视图只调用post
方法
当发布到user/{pk}/
时,您的请求将映射到UserViewSet.create
方法。对user/{pk}/edit/
的post请求映射到您的UserViewSet.edit
方法。在这两种情况下,都不会调用UserViewSet.post
似乎当您发布到不存在的自定义url时,会调用post
方法(可能是一种回退)。在您的例子中,address/search/
不是有效的url,而是将端点定义为address/{pk}/search/
如果要访问地址/search/
,则需要更新搜索方法,以使用列表路径
装饰器,而不是详细路径
:
class AddressViewSet(viewsets.ModelViewSet):
...
@list_route(methods=['post'])
def search(self, request, *args, **kwargs):
... (processing)
希望这有助于为您澄清问题。我很好奇如何使用浏览器发送POST
数据?我使用Jquery AJAX发送数据。您可以在shell中尝试curl:curl-I-X POST-H'内容类型:application/json'-d'{“name”:“john”,“address”:“google.com”}http://host/api/user/1/edit/
?看起来不错。返回与使用POST
相同的内容,我100%确定在执行search
时代码会运行。我已经尝试将响应(“post”)和响应(“函数”)
放在post中,并运行了两次以进行测试。您的post可能缺少实际代码中的某些内容。如果代码是按照您发布的方式构造的,那么就不会调用post()。假设您使用的是最新版本的REST框架。不管怎样,试试我的建议。它来自这里,类似这样:是的,您可能会注意到post()不在该页面的预定义方法列表中。post()用于APIView,而不是ViewSet。抱歉,我将其链接错了: