问题描述
之前也曾提出过类似的问题,但是我似乎无法用答案来解决问题。
我正在尝试部分更新对象,并且重写了REST的通用partial_update method
中的UpdateAPIView
,但是当我通过requests
调用此视图时,我得到了405:get method not allowed
响应
非常奇怪的是我的代码运行了大约2周,现在突然间我收到此错误。我把头撞在墙上,似乎无法弄清楚。
我认为我正在这样做:
class BuildingUpdateAPI(UpdateAPIView):
serializer_class = BuildingSerializer
def partial_update(self,request,*args,**kwargs):
"""Patches building specified in URL with data in request."""
network = Network.objects.get(name=self.kwargs["name_network"])
building = network.buildings.get(name=self.kwargs["name_building"])
serializer = BuildingSerializer(building,data=request.data,partial=True)
if serializer.is_valid():
serializer.save()
return JsonResponse(status=200,data=serializer.data)
msg = (
"Error message"
)
return JsonResponse(status=400,data=msg,safe=False)
我的序列化器很简单,它仅定义字段(但如果有帮助,我可以提供)。
在其他答案中,据说REST正在寻找get-method
并且找不到它。但是我不是通过get而是通过patch
来称呼它:
ep = "http://localhost:8000/path/to/update/"
data = {
"update_field": "123"
}
r = requests.request("patch",url=ep,data=data,headers=get_headers())
其他答案说我输入了错误的URL,但是我很确定这是正确的URL。再说一次,这是可行的,而现在却没有。还是我不能在更新方法中调用Network.objects.get
?但是那我怎么办...
并使这个事情变得更加荒谬:我可以使用REST接口进行更新。但是通过请求发送补丁请求会给我这个错误(但是我需要通过请求来做到这一点)
我真的没有选择,非常感谢您的帮助。提前致谢。如果我可以提供更多代码或信息,请输入lmk。
谢谢。
更新:同样通过Postman尝试此操作也会产生相同的错误,因此我认为请求不是问题。
urls.py:
urlpatterns = [
path(
"api/v1/networks/<int:pk>/",NetworkDetailAPIById.as_view(),name="networks-detail-api-id",),path(
"api/v1/networks/<str:name>/",NetworkDetailAPIByName.as_view(),name="networks-detail-api-name",path(
"api/v1/networks/update/<int:pk>/",NetworkUpdateAPI.as_view(),name="networks-update-api",path(
"api/v1/networks/buildings/new/",NetworkBuildingCreateAPI.as_view(),name="networks-buildings-create-api",path(
"api/v1/networks/project/<str:project_name>",NetworkProjectListAPI.as_view(),name="networks-project-list-api",path(
"api/v1/buildings/<int:id>/",BuildingRetrieveAPI.as_view(),name="buildings-detail-api",path(
"api/v1/buildings/delete/<int:id>",BuildingDeleteAPI.as_view(),name="buildings-delete-api",path(
"api/v1/buildings/update/<str:name_network>/<str:name_building>",BuildingUpdateAPI.as_view(),name="buildings-update-api",path(
"api/v1/network/buildings/<str:name_network>/",BuildingByNetworkListAPI.as_view(),name="network-buildings-list-api",path(
"api/v1/time-series/",TimeSeriesAPI.as_view(),name="time-series-list-create-api",path(
"api/v1/time-series/network/building/type-data/<str:name_network>/<str:name_building>/<str:type_data>/",TimeSeriesBuildingInNetworkAPI.as_view(),name="time-series-building-data-type-detail-api",path(
"api/v1/time-series/project/type-data/step/<str:project>/"
"<str:type_data>/<str:time_step>/",TimeStampBuildingsAPI.as_view(),name="timestamp-detail-api",path("api/v1/bldg/<str:name_network>/<str:name_building>/",SampleCreate.as_view(),name="sample")
]
添加get
时出错:
500
<!DOCTYPE html>
<html lang="en">
<head>
<Meta http-equiv="content-type" content="text/html; charset=utf-8">
<Meta name="robots" content="NONE,NOARCHIVE">
<title>AssertionError
at /de/api/v1/bldg/TestDevNetworkBuilding4/Demand_1/</title>
<style type="text/css">
html * { padding:0; margin:0; }
..... plus a bunch of html
解决方法
您的路径缺少端口组件:
ep = "http:localhost:/path/to/update/"
应该是这样的:
ep = "http:localhost:5000/path/to/update/"
更新:
尝试向该类添加patch
方法:
def patch(self,request,*args,**kwargs):
kwargs['partial'] = True
return self.partial_update(request,**kwargs)
然后,更改为:
r = requests.request("PATCH",url=ep,data=data,headers=get_headers())
或尝试:
r = requests.patch(url=ep,headers=get_headers())
更新2:
故障排除后:
这是来自/de/api/v1/bldg/TestDevNetworkBuilding4/Demand_1
的声明错误,与您的SampleCreate.as_view()
URL模式匹配。网址匹配path("api/v1/bldg/<str:name_network>/<str:name_building>/"
。
可能的原因:您在网址中混淆了建筑物和建筑物,或者添加了其他网址参数,例如语言de
,en
等。