How to get custom list view in django-rest-framework viewset

旧时模样 提交于 2021-02-07 11:54:32

问题


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 contains pk 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!