问题
I have a tv channel model and created a django-restframework viewlet which gives me a list and a detail view out of the box. On top I added two custom single-object views called all_events and now_and_next_event, as described here: Marking extra methods for routing. That works great so far.
class ChannelViewSet(viewsets.ModelViewSet):
"""
A viewset for viewing and editing channel instances.
"""
serializer_class = serializers.ChannelSerializer
queryset = Channel.objects.all()
@link()
def now_and_next_event(self, request, pk):
''' Show current and next event of single channel. '''
...
Now I would like to add a custom view which is NOT a single-object view but a list-like view:
class CurrentEvents(generics.ListCreateAPIView):
''' Show current event of all channels. '''
model = Event
serializer_class = serializers.EventSerializer
def get(self, request):
...
When I disable my viewlet and add a manual url pattern for it, it works as well. But I haven't figured out how to make them both work with the same 'api/channel/' prefix, or what I would like more, how to add the custom list view class into my viewlet.
Here are my viewlet url patterns:
^api/channel/$ [name='channel-list']
^api/channel/(?P<pk>[^/]+)/$ [name='channel-detail']
^api/channel/(?P<pk>[^/]+)/all_events/$ [name='channel-all-events']
^api/channel/(?P<pk>[^/]+)/now_and_next_event/$ [name='channel-now-and-next-event']
And I would like to access my list view like:
^api/channel/current_events/$ [name='event-current']
回答1:
As of Django REST Framework 2.4, you can now decorate ViewSet
methods with @list_route
to get what you are looking for.
From the documentation
The
@detail_route
decorator containspk
in its URL pattern and is intended for methods which require a single instance. The@list_route
decorator is intended for methods which operate on a list of objects.
These replace the old @link
and @action
decorators which were only able to work as detail routes.
回答2:
if you want list of objects then you need list method in your ListApiView: For example, model is ModelName and serializer class is SerializerClassname then code will be:
class ExampleView(ListAPIView):
model = ModelNmae
serializer_class = SerializerClassName
permission_classes = (IsAuthenticated,)
def get_queryset(self):
"""
"""
queryset = ModelName.objects.all()
q = self.request.query_params.get('q', None)
if q is not None:
queryset =queryset.filter(name__icontains=q)
return queryset
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
result = [ x.values()[0] for x in serializer.data ]
return Response(result)
来源:https://stackoverflow.com/questions/19921950/how-to-get-custom-list-view-in-django-rest-framework-viewset