django - REST 上的奇怪行为:更新/补丁视图不允许 get 方法并在通过请求调用时返回 405
问题描述
以前也有人问过类似的问题,但我似乎无法用答案解决我的问题。
我正在尝试部分更新一个对象,并且我覆盖了partial_update method
REST 的泛型UpdateAPIView
,但是当我通过调用这个视图时,requests
我得到了一个405:get method not allowed
-response。
非常奇怪的是,我的代码工作了大约 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 寻找 aget-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。
谢谢。
更新:通过邮递员尝试这个也会给出同样的错误,所以我猜这不是请求的问题。
网址.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, *args, **kwargs)
然后,更改为:
r = requests.request("PATCH", url=ep, data=data, headers=get_headers())
或尝试:
r = requests.patch(url=ep, data=data, 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>/"
匹配。
可能的原因:您在 url 中混淆了 bldg 和 building,或者添加了另一个 url 参数,例如 language de
、en
等。
推荐阅读
- c - 如何在C中获取数组参数的实际大小?
- android - 使用 Firebase 作业调度程序运行服务直到下一个计划
- avl-tree - 如何平衡 AVL 树中的悬空节点
- javascript - 更改每个选项的占位符文本
- javascript - 如何使用struts和jquery将行的值传递给单选按钮
- android-studio - 更新到 Android Oreo 后出现奇怪的编辑框
- xamarin.forms - 如何更改 Xamarin.forms 中选项卡项的大小
- asp.net-core - 来自 jsonschema 文件的 Swashbuckle 远程定义
- c# - C# Gradebook 程序,从文本文件中读取数据
- java - Java JSP servlet 500 错误