2

我在用户和图像之间建立了关系,每个用户都可以拥有多个图像。我需要定义一个端点来检索特定用户的所有图像:

GET /users/:id/images

我已经这样做了:

网址.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,似乎不是很吸引人。有更好的方法吗?

4

2 回答 2

2

在基本情况下,您最终会指定一个模型和一个序列化程序类。没有理由不能将这两个都放在某种表中并用于kwargs查找。

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

如果你这样做,以及覆盖get_queryset,你也可以覆盖get_serializer_class。然后你会有一些非常通用的东西。

我不是你真正要节省多少打字(特别是如果你使用编辑器的代码片段功能)。或者最终的系统会有多灵活。但这是一个有趣的想法。

于 2013-10-03T11:07:50.090 回答
2

您真的应该使用super()inget_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
于 2013-10-11T23:01:10.087 回答