您可以使用 Haystack 的 SearchView(而不是 DRF 视图),它会公开页面对象以进行分页。然后你可以把它传递给你的序列化器。
例如不久前,我正在处理需要在当前 HTML 页面上呈现结果的 json 对象的东西,所以我编写了一个过滤器标记来执行此操作(我们使用 FacetedSearchView 作为 UI,而 DRF 用于更通用的 RESTful API) .在模板中这样调用:
var articlesJson = {{ page.object_list|article_jsonify }}
实际过滤标签:
import collections
from django.template import Library
from django.utils.safestring import mark_safe
from rest_framework.renderers import JSONRenderer
register = Library()
def article_jsonify(object):
if isinstance(object, collections.Iterable):
many = True
ids = [obj.object.id for obj in object]
else:
many = False
ids = [object.id]
articles = Article.objects.filter(pk__in=ids)
serializer = ArticleSerializer(articles, many=many)
content = JSONRenderer().render(serializer.data)
return mark_safe(content)
register.filter('article_jsonify', article_jsonify)
您还可以编写一个继承自 generics.ListAPIView 的视图并覆盖 get_queryset 方法,您可以将请求的查询参数传递给 SearchQuerySet,然后使用 Serializer 将其输出。更多信息在这里:
http://www.django-rest-framework.org/api-guide/filtering
当然,您可能无法以这种方式使用 ModelSerializer,除非您执行您提到的操作。但是 DRF 有一个在查询集上使用分页器的示例,如下所示:
http://www.django-rest-framework.org/api-guide/pagination#paginating-querysets
更新
我最终使用了一个 DRF 视图,该视图使用 Haystack SearchQuerySet 作为查询集,然后将其传递给 Paginator。这是一个简化的示例(我相信它可以简化一些),但我希望它可以帮助某人入门。
class ArticleList(ListCreateAPIView):
"""
List, Create files
"""
model = Article
def get(self, request, *args, **kwargs):
# simplified filtering of an SQS
q = request.get('q', '')
sqs = SearchQuerySet().filter(content=Clean(q))
paginator = Paginator(sqs, 20)
page = request.QUERY_PARAMS.get('page')
try:
articles = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer, deliver first page
articles = paginator.page(1)
except PageNotAnInteger:
# If page is out of range, deliver last page
articles = paginator.page(paginator.num_pages)
serializer_context = {'request': request}
serializer = PaginatedArticleSerializer(articles, context=serializer_context)
return Response(serializer.data)
class ArticleSerializer(serializers.ModelSerializer):
"""
Base Article Serializer
"""
class Meta:
model = Article
class PaginatedArticleSerializer(pagination.PaginationSerializer):
"""
Serializes page objects of article querysets.
"""
start_index = serializers.SerializerMethodField('get_start_index')
end_index = serializers.SerializerMethodField('get_end_index')
num_pages = serializers.Field(source='paginator.num_pages')
class Meta:
object_serializer_class = ArticleSerializer
def get_start_index(self, page):
return page.start_index()
def get_end_index(self, page):
return page.end_index()
def get_curr_page(self, page):
return page.number