Unable to POST data with the Django REST Framework : Not Found

Question:

I’m trying to figure out why the Django REST Framework throws a 404 Not Found when I POST data with the code below, because when I load the browsable API with the URL it correctly displays the object list with the HTML form to POST data.

The Django project that serve the API run in a Docker container as well as the client, but in a separate Docker host.

How could I fix the issue ?

Server

Console logs

django-1         | Not Found: /api/strategy/target/
django-1         | [26/Sep/2022 14:27:05] "POST /api/strategy/target/ HTTP/1.1" 404 23

project/project/urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path("api/strategy/", include("strategy.urls")),
]

strategy/urls.py

from django.urls import path, include
from rest_framework import routers
from strategy.api.views import TargetViewSet


router = routers.DefaultRouter()
router.register("target", TargetViewSet, basename="targets-list")

urlpatterns = [
    path('', include(router.urls)),
]

strategy/views.py

from rest_framework import viewsets
from strategy.api.serializers import TargetSerializer
from rest_framework.decorators import permission_classes
from rest_framework.permissions import IsAdminUser


# Create new model
@permission_classes([IsAdminUser])
class TargetViewSet(viewsets.ModelViewSet):
    serializer_class = TargetSerializer
    queryset = Target.objects.all()

Client

res = requests.post("http://1.2.3.4:8001/api/strategy/target/",
                    data=data,
                    headers={'Authorization': 'Bearer {0}'.format(token)}
                    )
Asked By: Florent

||

Answers:

router.register("target", TargetViewSet, basename="targets-list")

The defination of the router is correct but I think the basename you have there is the problem. Since you have a queryset defined in your views, you can remove the basename completely. You only need to use basename if you define your own get_queryset function.

So try this and let’s see if it works out for you.

router.register("target", TargetViewSet")
Answered By: Sollych