2013-09-28 28 views
2

我在用戶和圖像之間有一種關係,每個用戶都可以有多個圖像。我需要定義檢索所有圖像爲特定用戶的端點:使用Django REST框架定義過濾端點的更好方法

GET /users/:id/images

我已經做了這樣的:

urls.py

router = routers.DefaultRouter() 
router.register(r'images', ImageViewSet) 

image_list = ImageViewSet.as_view({ 
    'get': 'list' 
}) 

urlpatterns = patterns('', 
    ... 
    url(r'^', include(router.urls)), 
    url(r'^users/(?P<user_id>[^/]+)/images/$', image_list), 
    ... 
) 

圖像/views.py

class ImageViewSet(viewsets.ModelViewSet): 
    queryset = Image.objects.all() 
    serializer_class = ImageSerializer 

    def get_queryset(self): 
     user_id = self.kwargs.get('user_id', None) 
     if user_id: 
      return Image.objects.filter(user_id=user_id) 
     return super(ImageViewSet, self).get_queryset() 

它的作品,但我不滿意。設想一些類似於/users/:user_id/images/的附加端點,即沿着/categories/:category_id/images/等行的一些端點。將get_queryset作爲這兩者的入口點,讓它根據kwargs進行區分,似乎不太吸引人。有沒有更好的方法來做到這一點?

+0

你的意思是一個方法,你必須在所有定義網址?那麼應用程序如何知道在哪裏服務? –

+0

我有一個想法是添加一個圖像動作到UserViewSet,用@link裝飾它,並重新使用ImageViewSet中的獲取動作。由於提出了我嘗試過的這個問題,但看起來並不像是很容易做到的事情。 –

+0

另外,仔細考慮了一下,手動定義一個url並不會讓我感到困擾,因爲我們不得不用這種方法來弄髒get_queryset方法。假設有一些類似於'/ users /:id/images'的附加端點,類似於'/ category /:category_id/images'等等,將get_queryset作爲所有這些入口的入口似乎很糟糕理念。 –

回答

2

在基本情況下,您最終會指定一個模型和一個序列化程序類。沒有理由爲什麼你不能將這兩個表放在某種表中,並使用kwargs來進行查找。

LOOK_UP_TABLE = { 
    'users' : { 
     'model': ..., 
     'serializer_class': ..., 
    }, 
    'categories' : { 
     ... 
    }, 
} 

如果你這樣做,以及覆蓋get_queryset,您可以覆蓋get_serializer_class了。你會有一些非常通用的東西。

我不是多少打字你真的要保存(尤其是如果你使用你的編輯器的代碼片段功能)。或者由此產生的系統有多靈活。但這是一個有趣的想法。

2

你真的應該使用super()get_queryset()得到未過濾的查詢集,並根據kwargs只是過濾它。

if user_id: 
    super(ImageViewSet, self).get_queryset().filter(user_id=user_id) 

你會發現,這將成爲非常通用的,可以納入每個視圖作爲一個mixin:

class FilterByUserMixin(object): 
    def get_queryset(self): 
     user_id = self.kwargs.get('user_id', None) 
     queryset = super(FilterByUserMixin, self).get_queryset() 
     if user_id: 
      queryset = queryset.filter(user_id=user_id) 
     return querset 


class ImageViewSet(FilterByUserMixin, viewsets.ModelViewSet): 
    queryset = Image.objects.all() 
    serializer_class = ImageSerializer 


class CategoryViewSet(FilterbyUserMixin, viewsets.ModelViewSet): 
    queryset = Category.objects.all() 
    serializer_class = CategorySerializer