【问题标题】:How to get custom list view in django-rest-framework viewset如何在 django-rest-framework 视图集中获取自定义列表视图
【发布时间】:2013-11-12 05:55:12
【问题描述】:

我有一个电视频道模型并创建了一个 django-restframework viewlet,它为我提供了一个开箱即用的列表和详细视图。在顶部,我添加了两个名为 all_events 和 now_and_next_event 的自定义单对象视图,如下所述:Marking extra methods for routing。到目前为止效果很好。

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. '''
        ...

现在我想添加一个自定义视图,它不是单对象视图,而是类似列表的视图:

class CurrentEvents(generics.ListCreateAPIView):
    ''' Show current event of all channels. '''
    model = Event
    serializer_class = serializers.EventSerializer

    def get(self, request):
        ...

当我禁用我的 viewlet 并为其添加手动 url 模式时,它也可以正常工作。但我还没有弄清楚如何让它们都使用相同的 'api/channel/' 前缀,或者我想要更多,如何将自定义列表视图类添加到我的 viewlet 中。

这是我的 viewlet url 模式:

^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']

我想访问我的列表视图,例如:

^api/channel/current_events/$ [name='event-current']

【问题讨论】:

标签: django django-rest-framework


【解决方案1】:

如果你想要对象列表,那么你需要 ListApiView 中的 list 方法: 例如,模型是 ModelName,序列化程序类是 SerializerClassname 那么代码将是:

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)

【讨论】:

    【解决方案2】:

    从 Django REST Framework 2.4 开始,您现在可以使用 @list_route 装饰 ViewSet 方法以获得所需的内容。

    From the documentation

    @detail_route 装饰器在其 URL 模式中包含 pk,适用于需要单个实例的方法。 @list_route 装饰器适用于对对象列表进行操作的方法。

    这些替换了旧的 @link@action 装饰器,它们只能用作详细路由。

    【讨论】:

    • 自 3.8 起,@detail_route@list_route 正在等待弃用,以支持 @action(detail=True)@action(detail=False)。 (这些将在 3.9 中弃用并在 3.10 中删除)。
    猜你喜欢
    • 2018-10-18
    • 1970-01-01
    • 2021-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-06
    • 2018-09-04
    • 2018-12-12
    相关资源
    最近更新 更多