This is my first project with Django and I am having a bit of trouble with the URLs.
I have a customer model and I created the ModelViewSet
for it so I can retrieve, delete and update the models in the database.
To get all the basic URLs I used rest_framework.routers.DefaultRouter
and registered the CustomerViewSet
to it like so:
router = routers.DefaultRouter()
router.register(r'customers', CustomerViewSet, basename='customers')
And then registered the URLs like so:
urlpatterns = [
path('', include(router.urls), name="customers"),
]
My problem is that I need to add a new URL for deleting all the customers in the database.
I tried adding it like so:
urlpatterns = [
path('', include(router.urls), name="customers"),
path('customers/', deleteAllCustomers, name='deleteAll'),
]
Where deleteAllCustomers
is a function decorated with api_view(['DELETE']
.
When I try to call this URL (using Postman), I get 405 error (method 'DELETE' not allowed).
From what I understand, it happens because that URL is already assigned by the DefaulteRouter
for PUT/POST methods.
I tried adding a destroy
function to my CustomerViewSet
, but it is only called when deleting one instance (with primary key passed in the URL).
I haven't found a way to make the URL work and wasn't able to find any similar question.
CodePudding user response:
Looking at your code snippet. The url path for deleteAllCustomers
and CustomerViewSet
are the same i.e .../customers
I think your app urls.py file should look like this:
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from customers import views
router = DefaultRouter()
router.register('', views.CustomerViewSet,
basename="customers")
app_name = 'customers'
urlpatterns = [
path('customers/', deleteAllCustomers, name='deleteAll'),
path('', include(router.urls)),
]
The order of the url patterns is important.
Your views.py file for CustomerViewSet
should look like this to support: GET,CREATE,PUT,PATCH,RETRIEVE,DELETE
from rest_framework import viewsets, mixins, permissions, authentication
class CustomerViewSet(viewsets.GenericViewSet,
mixins.ListModelMixin,
mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyMixin
):
authentication_classes = (authentication.TokenAuthentication,)
permission_classes = (permissions.IsAuthenticated)
serializer_class = serializers.CustomerModelSerializer
queryset = models.Customers.objects.all()
Then you can set up your deleteAllCustomers
views how you want to.
CodePudding user response:
Thanks to Oluwatomisin Omotosho James for helping me with this.
I forgot to mention that in my case I need the URL /customers/
to support both the POST
and DELETE
methods.
So I changed the deleteAllCustomers
function to also handle the POST
request.
(And like they suggested, reordering the urlpatterns
array)
The code now works great