如何有效地对字段分页django queryset?

时间:2017-06-23 12:56:35

标签: django django-rest-framework django-pagination

我有一个带有Boolean字段的模型,我希望通过Boolean字段对此模型的查询集进行分页:

  1. 页面大小为10
  2. 每个页面包含Boolean字段所在的2个项目 True以及Boolean字段为False
  3. 的8个项目
  4. 如果一个页面不能满足规则2,例如在分页后剩余的项目具有False值,则只需将它们附加到页面
  5. 例如:

    使用Food模型,我希望每页有2种脂肪食物和8种非脂肪食物

    class Food(models.Model):
        # whether fat food 
        is_fat_food = models.BooleanField(default=False)
        # other field
    

    现在,我在get_queryset中使用以下算法实现分页。顺便说一句,我在界面中使用ListModelMixin来实现分页。

    def get_queryset(self):
        fat_food_qs = Food.objects.filter(is_fat_food=True)
        non_fat_food_qs = Food.objects.filter(is_fat_food=False)
        final_qs = []
        fat_page_size = 2
        no_fat_page_size = 8
        i = 0
        j = 0
        while i < len(fat_food_qs) and j < len(non_fat_food_qs):
            if i + fat_page_size > len(fat_food_qs):
                break
            if j + no_fat_page_size > len(non_fat_food_qs):
                break
            final_qs += fat_food_qs[i:i+fat_page_size]
            final_qs += non_fat_food_qs[j:j+non_fat_food_qs]
            i += fat_page_size
            j += non_fat_food_qs
        # remaining food no need to obey the rule, just append
        if i < len(fat_food_qs):
            final_qs += fat_food_qs[i:]
        if j < len(non_fat_food_qs):
            final_qs += non_fat_food_qs[j:]
        return final_qs
    

    通过这种算法,我得到了正确的和预期的结果,但我认为它效率不高。

    因为基于查询集的默认分页算法使用延迟加载机制,它只在请求页面时加载一个特定页面。

    但是在我的算法中,我需要在分页之前遍历并处理查询集。

    我是django的新生,我不知道是否需要在不使用ListModelMixin的情况下实施分页,只需基于请求参数pagepage_size即可获取特定页面查询结果并构建prevnext页面链接作为响应。

    任何建议都将不胜感激。

    PS:我也是python的新手,如果有任何代码不是pythonic,请告诉我,谢谢。

1 个答案:

答案 0 :(得分:0)

django核心中有一个paginator

{{1}}

上面的解决方案不会比针对非常少的数据库行的答案提供更好的优势,但它对大数据的性能会更好。