I can't get @detail_route to work as I think it is supposed to.
I have two API calls I want to handle:
/movie/
/movie/highlight
I am trying to use @detail_route to pickup the /movie/highlight url in the viewset.
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'users', views.UsersViewSet)
router.register(r'groups', views.GroupViewSet)
router.register(r'movie', views.MovieViewSet)
My views.py looks like this:
rom 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 detail_route
# Code from DRF quickstart tutorial
class UsersViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = User.objects.all().order_by('-date_joined')
serializer_class = UserSerializer
# Code from DRF quickstart tutorial
class GroupViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows groups to be viewed or edited.
"""
queryset = Group.objects.all()
serializer_class = GroupSerializer
# MY CODE
class MovieViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows groups to be viewed or edited.
"""
queryset = Movie.objects.all().order_by('-title')
serializer_class = MovieSerializer
@detail_route(renderer_classes=(renderers.StaticHTMLRenderer,))
def highlight(self, request, *args, **kwargs):
snippet = "Highlight"
return Response(snippet)
The serializers.py looks like this:
from django.contrib.auth.models import User, Group
from movies.models import *
from rest_framework import serializers
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('url', 'username', 'email', 'groups')
class GroupSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Group
fields = ('url', 'name')
# My code...
class MovieSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Movie
fields = ('title', 'details')
If I try the /movie/ url API call it works as expected. If I try the /movie/highlight/ call I get a 404 error.
I am a newbie to DRF so suspect I am doing something very silly here but can't find out what from the various docs and tutorials I have scanned.
答案 0 :(得分:5)
You need to use @list_route
decorator instead of @detail_route
decorator.
This will generate the url movie/highlight/
.
Using @list_route
decorated method generates the url of type {prefix}/{methodname}/
whereas detail_route
decorated method generateds url of type {prefix}/{lookup}/{methodname}/
. Here methodname
is name of your method and lookup
is the lookup value on which lookup is performed to get the object for detail view.
class MovieViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows groups to be viewed or edited.
"""
queryset = Movie.objects.all().order_by('-title')
serializer_class = MovieSerializer
# use list_route decorator
@list_route(renderer_classes=(renderers.StaticHTMLRenderer,))
def highlight(self, request, *args, **kwargs):
snippet = "Highlight"
return Response(snippet)
答案 1 :(得分:0)
If you register your URLs using routers.DefaultRouter(), it will generate the URL /movie/pk/highlight instead of /movie/highlight. If you want a custom URL other than the pre-generated one, use URL mapping.