【问题标题】:django Rest Framework - ViewSet with custom list view and URL parameterdjango Rest Framework - 具有自定义列表视图和 URL 参数的 ViewSet
【发布时间】:2018-09-04 19:56:08
【问题描述】:

我有以下设置:

我想列出特定年份的所有假期。这就是为什么我省略了默认列表视图并像这样实现我自己的:

class HolidayViewSet(mixins.RetrieveModelMixin, GenericViewSet):
@list_route()
def year(self, request, year=get_today().year):
    public_holidays = self.get_queryset().filter(date__year=year)
    page = self.paginate_queryset(public_holidays)
    if page is not None:
        serializer = self.get_serializer(page, many=True)
        return self.get_paginated_response(serializer.data)
    serializer = self.get_serializer(public_holidays, many=True)
    return Response(serializer.data)

如果我使用默认的 /holiday/year/ 我会得到当前年份的结果。

但是当我尝试传递参数时,我会得到一个 404。404 页面(在调试模式下)甚至显示了正确的 URL 模式:

api/v1/ ^holiday/year/$ [name='holiday-year']
api/v1/ ^holiday/year\.(?P<format>[a-z0-9]+)/?$ [name='holiday-year']

documentation 中很遗憾没有涵盖这一方面。

任何想法为什么我到holiday/year/2017 的路线不起作用?

谢谢! 罗恩

【问题讨论】:

标签: django django-rest-framework


【解决方案1】:

好的,我的解决方法是使用django-filter

我的过滤器:

class HolidayFilter(filters.FilterSet):
    """
    This filter can be used to filter holidays by different values in API views or viewsets.
    See http://django-filter.readthedocs.io/en/1.1.0/guide/rest_framework.html
    """
    year = filters.NumberFilter(name='date', lookup_expr='year')

    class Meta:
        model = Holiday
        fields = ['date']

我的观点:

class HolidayListViewSet(ModelViewSet):

    def list(self, request, *args, **kwargs):
        # Apply filters
        queryset = self.filter_queryset(self.get_queryset())
        page = self.paginate_queryset(queryset)
        # Pagination
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        # Serializer
        serializer = self.get_serializer(queryset, many=True)
        # Response
        return Response(serializer.data)

网址:

/api/v1/holiday/?year=2016

感谢您的支持,也许这对其他人有帮助!

【讨论】:

    【解决方案2】:

    DRF 区分 listdetail 请求。 list 请求不应有额外的路径参数(即/{id}),而detail 请求则相反,由它定义。

    意思是@list_route装饰器创建/holiday/year端点,@detail_route将创建/holiday/{id}/year端点。

    【讨论】:

    • 好吧,关于 404 页面,我得到了一条我想要的路线。即使使用 list_route。但是我该如何使用它呢?
    • @Ron “我得到了一条我想要的路线”——不完全是。 ^holiday/year\.(?P&lt;format&gt;[a-z0-9]+)/?$ 生成格式为holiday/year.[a-z0-9]+ 的路径。不是holiday/year/{id}
    • 我知道。但不幸的是——正如我所指出的——我无法使用这条路线。我没有尝试 id,我尝试了多年。
    【解决方案3】:

    我认为我的方法很简单但很有用。只需确定您的路由器,如下所示:

    urlpatterns += [
        path(r'holiday/<int:year>/', TestListView.as_view()),
    ]
    

    网址:

    api/v1/holiday/2016/

    然后像这样创建你的视图:

    class TestListView(generics.ListAPIView):
        serializer_class = TestSerializer
    
        def get(self, request, *args, **kwargs):
            year = kwargs.get('year', '')
            query_set = Test.objects.filter(year__exact=year) # Test is my test model
            serializer = self.get_serializer(query_set, many=True)
            return Response(serializer.data)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-07
      • 1970-01-01
      • 1970-01-01
      • 2015-03-02
      • 1970-01-01
      • 1970-01-01
      • 2018-12-12
      • 2018-10-18
      相关资源
      最近更新 更多