我在用户和图像之间建立了关系,每个用户都可以拥有多个图像。我需要定义一个端点来检索特定用户的所有图像:
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 :(得分:2)
在基本情况下,您最终指定了模型和序列化程序类。没有理由不能将这两者放在某种表格中并使用kwargs
进行查找。
LOOK_UP_TABLE = {
'users' : {
'model': ...,
'serializer_class': ...,
},
'categories' : {
...
},
}
如果您这样做,以及覆盖get_queryset
,您也可以覆盖get_serializer_class
。然后你会有一些非常通用的东西。
我不是在节省多少打字(特别是如果您使用编辑器的代码片段功能)。或者最终系统的灵活性如何。但这是一个有趣的想法。
答案 1 :(得分: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