【发布时间】:2014-12-31 23:01:36
【问题描述】:
我在对按rest_framework 的SerializerMethodField 排序的json 数据进行分页时遇到问题。在开始向列表视图添加分页之前,我将排序后的 json 数据放在上下文变量中,如下所示:
class ExampleList(ListView):
...
def get_context_data(self, **kwargs):
context = super(ExampleList, self).get_context_data(**kwargs)
context["examples"] = sorted(ExampleSerializer(
submissions, many=True, context={'request': self.request}
).data, key=lambda x: x.get("score"), reverse=True)
return context
...
这很有效,因为 lambda 函数抓取了分数,并按它排序,这正是 sorted() 应该如何工作的。问题始于分页。我已经研究了几天,没有任何方法可以通过我可以找到的json数据进行分页。仅通过查询集。
当我开始分页时,这是我的两个序列化程序类:
class ExampleSerializer(serializers.ModelSerializer):
score = serializers.SerializerMethodField('get_score')
class Meta:
model = Example
fields = ('id', '...', 'score',)
def get_score(self, obj):
return obj.calculate_score()
class PaginatedExampleSerializer(pagination.PaginationSerializer):
class Meta:
object_serializer_class = ExampleSerializer
在我的一个列表视图中,我创建了一个排序的上下文对象,它按score 对序列化数据进行排序并对其进行分页。我还创建了一个调用分页的方法,称为paginate_examples()。如您所见,它首先按查询集分页,然后在每个分页页面上按score 对数据进行排序。所以应该在第 1 页上的东西一直在第 5 页左右。
class ExampleList(ListView):
queryset = Example.objects.all()
def paginate_examples(self, queryset, paginate_by):
paginator = Paginator(queryset, paginate_by)
page = self.request.GET.get('page')
try:
examples = paginator.page(page)
except PageNotAnInteger:
examples = paginator.page(1)
except EmptyPage:
examples = paginator.page(paginator.num_pages)
return PaginatedExampleSerializer(examples, context={'request': self.request}).data
def get_context_data(self, **kwargs):
context = super(ExampleList, self).get_context_data(**kwargs)
pagination = self.paginate_examples(self.queryset, self.paginate_by)
examples = pagination.get("results")
context["examples"] = sorted(examples, key=lambda x: x.get("score"), reverse=True)
context["pagination"] = pagination
return context
同样,问题在于应该在/?page=1 上显示的列表项正在/?page=x 上显示,因为PaginatedExampleSerializer 在数据被SerializerMethodField 排序之前对数据进行了分页。
有没有办法对已经序列化的数据进行分页,而不是在 Django 中通过queryset 进行分页?还是我必须自己创建一些方法?我想避免将score 设为数据库字段,但如果我无法找到解决方案,那么我想我将不得不这样做。
对此的任何帮助将不胜感激。
【问题讨论】:
标签: django pagination django-rest-framework