簡體   English   中英

django Rest 框架 - 具有自定義列表視圖和 URL 參數的 ViewSet

[英]django Rest Framework - ViewSet with custom list view and URL parameter

我有以下設置:

我想列出特定年份的所有假期。 這就是為什么我省略默認列表視圖並像這樣實現我自己的列表視圖:

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

不幸的是,在文檔中沒有涵蓋這方面的內容。

知道為什么我去holiday/year/2017的路線不起作用嗎?

好的,我的解決方法是使用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

感謝您的支持,也許這有助於其他人!

DRF區分listdetail請求。 list請求不應該有額外的路徑參數(即/{id} ),而detail請求則相反,由它定義。

這意味着@list_route裝飾器創建/holiday/year ,而@detail_route將創建/holiday/{id}/year

我認為我的方法很簡單但很有用。 只需像下面這樣確定您的路由器:

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

URL:

api/v1/假期/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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM