Similar questions have been asked before, but I can't seem to fix my problem with the answers.
I am trying to partially update an object and I overwrote the partial_update method
in REST's generic UpdateAPIView
but when I call this view via requests
I get a 405:get method not allowed
-response.
What is extremely odd is that my code was working for about 2 weeks and now all of the sudden I get this error. I'm banging my head against a wall and can't seem to figure this out.
In my view I am doing this:
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)
My serializer is simple, it only defines the fields (but I can provide it if it helps).
In other answers it is said that REST looks for a get-method
and can't find it. But I am calling this not via get, but via patch
:
ep = "http://localhost:8000/path/to/update/"
data = {
"update_field": "123"
}
r = requests.request("patch", url=ep, data=data, headers=get_headers())
Other answers say I am calling a wrong URL, but I am quite sure that it is the correct URL. And again, this was working before and now it doesn't . Or can I not call Network.objects.get
within an update method? But that how could I do anything then...
And to make this thing even more ridiculous: I can update just fine using with REST-interface. But sending a patch-request via requests gives me that error (But I need to do that with requests)
I'm really out of options, any help is very much appreciated. Thanks in advance. If I can provide any more code or info just lmk.
Thanks.
Update: Also trying this via Postman gives the same error, so it's not a problem with requests I guess.
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")
]
Error when adding 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
Your path is missing the port component:
ep = "http:localhost:/path/to/update/"
should be something like:
ep = "http:localhost:5000/path/to/update/"
UPDATE:
Try adding a patch
method to the class:
def patch(self, request, *args, **kwargs):
kwargs['partial'] = True
return self.partial_update(request, *args, **kwargs)
Then, change to :
r = requests.request("PATCH", url=ep, data=data, headers=get_headers())
or try:
r = requests.patch(url=ep, data=data, headers=get_headers())
UPDATE 2:
After troubleshooting:
That's an assertion error from /de/api/v1/bldg/TestDevNetworkBuilding4/Demand_1
which matches your SampleCreate.as_view()
URL pattern. The url is hitting the path("api/v1/bldg/<str:name_network>/<str:name_building>/"
match.
Possible causes: you are confusing bldg and buildings in your url, or adding another url parameter, like language de
, en
, etc.