Reputation: 534
We're building an API with Django Rest Framework, and our clients want it to have this endpoint:
Method: POST
URL: api/v1/application/<id>
It's basically an update endpoint but with POST instead of PUT.
I already have a viewset for this model, and we're using the create, list, and retrieve actions.
So, one thing I can do is to allow POST for update actions in Django Rest Framework, but I haven't found how to do that. Also, I can define a custom action like this:
@action(methods=['post'], detail=True)
def update_status(self, request, pk=None):
# some code
The problem is this routes to application/<id>/update_status
, I can change the route by passing the url_path
parameter, but if it's None or empty it just defaults to update_status
again.
I can also just define this endpoint in a different view and route manually, but that's a worse solution in my opinion, it would be nice to have it in the viewset I already have.
Thanks.
Upvotes: 6
Views: 4713
Reputation: 1152
Django REST framework allows binding viewsets to URLs explicitly. You can create a set of views from your viewset and bind the URLs without a router
views.py
from restframework import viewsets, mixins
class ApplicationViewSet(mixins.ListModelMixin,
mixins.RetrieveModelMixin,
mixins.CreateModelMixin,
viewsets.GenericViewSet):
# Your viewset settings
def update(self, request, pk=None):
# Your code
urls.py
from django.urls import path, include
from .views import ApplicationViewSet
app_list = ApplicationViewSet.as_view({
'get': 'list',
'post': 'create'
})
app_detail = ApplicationViewSet.as_view({
'get': 'retrieve',
'post': 'update', # POST instead PUT
})
urlpatterns = [
path('application/', app_list, name='application-list'),
path('application/<int:pk>/', app_detail, name='application-detail'),
]
Upvotes: 3
Reputation: 189
I just had to do this and found that this works when setting up the router in urls.py
:
router = routers.SimpleRouter()
# Post Edit route.
router.routes[2].mapping['post'] = 'partial_update'
router.register(r'things', ThingViewSet)
The alternative is you build your own Router. Which isn't to bad either.
For reference here's the bit of code that defines the array this changes.
Upvotes: 1