Reputation: 6744
I am currently using Django REST Framework with routers and viewsets to handle the following API calls:
/movie/
/movie/highlight
/movie/<id>/other
I can't seem to find a way to extend the viewset to handle, in addition to the above, the following API calls:
/movie/<id>
/movie/<id>/other/<num>
My views.py currently looks like this:
from django.contrib.auth.models import User, Group
from movies.models import Movie
from api.serializers import UserSerializer, GroupSerializer, MovieSerializer
from rest_framework.response import Response
from rest_framework import permissions
from rest_framework import renderers
from rest_framework import viewsets
from rest_framework.decorators import list_route, detail_route
class MovieViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows groups to be viewed or edited.
"""
queryset = Movie.objects.all().order_by('-title')
serializer_class = MovieSerializer
# Handle URL: /movie/highlight
@list_route(renderer_classes=(renderers.StaticHTMLRenderer,))
def highlight(self, request, *args, **kwargs):
print "highlight"
snippet = "Highlight"
return Response(snippet)
# Handle URL: /movie/<id>/other
@detail_route(renderer_classes=(renderers.StaticHTMLRenderer,))
def other(self, request, *args, **kwargs):
print "highlight" + self.kwargs['pk']
snippet = "Highlight" + self.kwargs['pk']
return Response(snippet)
My urls.py looks like this:
from django.conf.urls import url, include
from rest_framework import routers
from api import views
router = routers.DefaultRouter()
router.register(r'movie', views.MovieViewSet)
urlpatterns = [
url(r'^', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]
I have searched high and low for an example of how to do this, including all of the DRF documentation, but haven't found anything relevant.
Upvotes: 2
Views: 1677
Reputation: 10325
You need to use this library to have nested resources https://github.com/alanjds/drf-nested-routers
sample code from one of my projects using this lib
class NestedChatViewSet(
viewsets.mixins.CreateModelMixin,
viewsets.mixins.ListModelMixin,
viewsets.GenericViewSet):
queryset = Chat.objects.all()
serializer_class = ChatSerializer
permission_classes = (IsAuthenticated, IsUserVerified, IsUserSignedPrivacyAgreement, IsUserOfConsent, )
def get_queryset(self):
return Chat.objects.filter(consent=self.kwargs['consent_pk']).order_by('-created')
def get_consent(self, request, pk=None):
consent = get_object_or_404(Consent, pk=pk)
self.check_object_permissions(self.request, consent)
self.consent = consent
return self.consent
def create(self, request, *args, **kwargs):
self.get_consent(request, pk=kwargs['consent_pk'])
return super().create(request, *args, **kwargs)
def perform_create(self, serializer):
serializer.save(
user=self.request.user,
consent=self.consent
)
def list(self, request, *args, **kwargs):
self.get_consent(request, pk=kwargs['consent_pk'])
return super().list(request, *args, **kwargs)
and then in url.py
router = DefaultRouter()
router.register(r'users', PeopleViewSet)
router.register(r'consents', ConsentViewSet)
consents_router = NestedSimpleRouter(router, r'consents', lookup='consent')
consents_router.register(r'chat', NestedChatViewSet)
and now you can get GET, POST consents/ID/chat you can have unlimited amount of nested resources here.
good tutorial is here http://www.machinalis.com/blog/nested-resources-with-django/
Upvotes: 3