在django rest框架中添加元数据到过滤

时间:2014-04-16 13:46:09

标签: django django-rest-framework

我有一个通用ListCreateAPIView视图。我已经实现了一个执行搜索的get_queryset函数。该函数解析查询,提取标签和术语并返回查询集。

def get_queryset(self):
        query = self.request.QUERY_PARAMS.get('query', None)

        # No deleted items
        queryset = Items.objects.filter(deleted__isnull=True)

        if query is None:
            return queryset

        predicates = []

        # Generate predicates from query       

        queryset = queryset.filter(reduce(__and__,predicates))
        return queryset

使用get_queryset功能的数据向响应添加元数据的最佳方法是什么?

我正在寻找类似于分页方式的东西。

{
 query : {
     terms : ['term1','term2'], 
     tags  : ['tag1','tag2'] , 
    }
 results : [
      { name : 'item1', .... }
      { name : 'item2', .... }
   ]
}

修改

所以我为过滤创建了一个自定义FilterBackend,现在我有一个请求和响应的实例。看看django休息的分页代码,我看到它将结果包装在序列化器中。分页是构建到视图类中的,因此如果检测到分页符,fw将调用序列化。查看搜索API并没有产生任何新的想法。

我的问题仍然是,将过滤器后端的元数据添加到响应中的最佳和最少侵入性方法是什么?

我能想到的一种方式(以及我不喜欢的方法)是将matadata重载到过滤器后端的请求中并覆盖视图中的finalize_response - 毫无疑问是最糟糕的方法它。

1 个答案:

答案 0 :(得分:5)

我不确定这是最好的方法,但是我可能会覆盖get来简单地拦截响应对象并修改response.data。像

这样简单的东西
from rest_framework import generics

class SomeModelList(generics.ListCreateAPIView):
    """
    API endpoint representing a list of some things.
    """

    model = SomeModel
    serializer_class = SomeModelSerializer

    def get(self, request, *args, **kwargs):
        response = super(SomeModelList, self).get(request, *args, **kwargs)

        # redefine response.data to include original query params
        response.data = {
            'query': dict(request.QUERY_PARAMS),
            'results': response.data
        }

        return response

如果您发现自己在多个列表视图中重复此操作,则可以使用Mixin将自己保持干燥并将其包含在列表API类中:

from rest_framework import generics
from rest_framework.mixins import ListModelMixin

class IncludeQueryListMixin(ListModelMixin):
    def list(self, request, *args, **kwargs):
        response = super(IncludeQueryListMixin, self).list(request, *args, **kwargs)

        # redefine response.data to include original query params
        response.data = {
            'query': dict(request.QUERY_PARAMS),
            'results': response.data
        }

        return response


class SomeModelList(IncludeQueryListMixin, generics.ListCreateAPIView):
    """
    API endpoint representing a list of some things.
    """

    model = SomeModel
    serializer_class = SomeModelSerializer