2016-04-20 98 views
0

我有一個端點,使用url kwargs,我想過濾並返回一個querySet,如下所示:/ api/myendpoint/{id} /應該返回所有myendpoint對象字段X匹配{id}。我在我的視圖類中提供了get_query_set方法,它是一個ReadOnlyModelViewSet,它返回一個查詢集,其中包含符合條件的所有對象(我知道這部分工作,因爲我在返回結果前打印出結果並且看起來正確)。Django ReadOnlyModelViewSet:get_querySet通過pk篩選

我似乎遇到的問題是get_queryset返回的查詢集似乎在被顯示在端點上之前再次被django過濾。它正在過濾,以便pk == {id}。這不是我想要的功能,因爲我使用{id}在不同的字段上進行過濾。它似乎被視爲DetailView,但我希望它被視爲一個集合視圖(如果存在這樣的事情)。如何在使用url kwargs的同時爲此視圖返回多個對象?我是一個django初學者,所以很抱歉,如果這是顯而易見的。

urls.py:

from rest_framework_nested_import routers 
    router = routers.DefaultRouter() 
    router.register(r'', MyView, base_name='myendpoint') 

    urlpatterns = patterns('', 
        url(r'^', include(router.urls))) 

views.py:

class MyView(viewsets.ReadOnlyModelViewSet): 

def get_queryset(self): 
     if 'pk' in self.kwargs: 
      return MyObj.objects.filter(field=self.kwargs['pk']) 

回答

1

回訪你不應該在/{pk}/傳遞,因爲這將嘗試並獲得一個單一的對象與ID集合,你已經看到了。

您應該用來獲取對象列表的正確URL是/api/myendpoint/。您可以使用queryset屬性或get_queryset函數篩選對象列表。但是,我們仍然需要讓django知道要過濾的字段和值。

這就是filtering by query parameter的地方。你也可以過濾URL字符串,但它有點複雜,因爲你需要修改你的路由器的URL。

class MyView(viewsets.ReadOnlyModelViewSet): 

    def get_queryset(self): 
     queryset = MyObj.objects.all() 
     filter_value = self.request.query_params.get('field_name', None) 
     if filter_value is not None: 
      queryset = queryset.filter(field_name=filter_value) 
     return queryset 

有了這個代碼,你可以打/api/myendpoint/?field_name=somevalue,它會通過someValue中返回MyObj中模型濾波FIELD_NAME的查詢集。

+0

謝謝!那麼,沒有辦法用/ api/myendpoint/{pk}/endpoint返回對象列表?我必須使用查詢參數?這使得使用api稍微不太直觀...... – dz210

+1

你可以,但是這將是一個ID爲{{pk}'detail_route的對象的動作。你想要做的是在list_route http://www.django-rest-framework.org/api-guide/viewsets/#marking-extra-actions-for-routing 如果你需要過濾在url本身,而不是查詢參數,你當然可以,但是你需要改變由'ViewSet'生成的默認URL路由。http://www.django-rest-framework.org/api-guide/過濾/#濾波抵最URL – awwester