动态更改 paginate_by 的值

Al *_*l G 2 django pagination

我希望能够允许用户更改默认页面大小 (paginate_by)。我当前的页面大小设置为 10;我想要按钮,比如 25、50 和所有。

我正在使用 postgresql 11.4 运行 Django 2.2 和 Python 3.73。我的 views.py 创建一个查询集并设置分页。我的 prod_list.html 模板以每页十行的方式正确显示页面中的数据。

这是我目前在 views.py 中的内容:

class ProdViewSet(viewsets.ModelViewSet):

    queryset = Proddetails.objects.all()
    serializer_class = ProdSerializer


class ProdListView(ListView):
    model = Proddetails
    template_name = 'prod_list.html'
    # added for pagination
    context_object_name =  'prods' #Default: object_list
    paginate_by = 10
Run Code Online (Sandbox Code Playgroud)

我希望能够让我的用户更改每页的行数。我想我需要根据用户单击的按钮重置paginate_by,但我该怎么做?

谢谢 -

好吧,我试图发表评论,但这并没有给我足够的空间。我希望这是执行此操作的正确方法:

非常感谢; 这样做的伎俩。不过,我修改了它以给我带页码的按钮,但我得到了一个奇怪的行为。我有一个 for 循环,用于将页码作为按钮输出:

{% for i in DataPaginated.paginator.page_range %}
  {% if DataPaginated.number == i %}
    <button class="w3-button w3-amber">{{ i }} </button>
  {% else %}
    <a href="?page={{ i }}" class="w3-button">{{ i }}</a>
  {% endif %}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

如果分页设置为默认值 10,这将正常工作并显示三页(有 24 个项目)。如果我将分页更改为 20,它起初看起来是正确的并显示两页。但是,如果我单击第二页,它会将我的分页更改回 10,再次显示三页,并将我放在三页中的第二页。我可以做些什么来将我的分页锁定在表单选择的设置中?

小智 8

您不需要重写 get 方法,正确的方法是重写该方法get_paginate_by

  class VideoView(ListView):
    template_name = "pages/videos.html"
    model = models.Video
    paginate_by = 10

    def get_paginate_by(self, queryset):
        return self.request.GET.get("paginate_by", self.paginate_by)
Run Code Online (Sandbox Code Playgroud)

现在您可以过滤:http://localhost:8000/videos/?paginate_by=40

问候。


Bob*_*ite 5

from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
    
class ProdListView(ListView):
    model = Proddetails
    template_name = 'prod_list.html'
    # added for pagination
    context_object_name =  'prods' #Default: object_list
    paginate_by = 10
    
    def get(self, request):

        paginate_by = request.GET.get('paginate_by', 10) or 10
        data = self.model.objects.all()

        paginator = Paginator(data, paginate_by)
        page = request.GET.get('page')

        try:
            paginated = paginator.get_page(page)
        except PageNotAnInteger:
            paginated = paginator.get_page(1)
        except EmptyPage:
            paginated = paginator.page(paginator.num_pages)

        return render(request, self.template_name, {'DataPaginated':paginated, 'paginate_by':paginate_by})
Run Code Online (Sandbox Code Playgroud)

你应该把它放在你的模板中以允许用户选择分页。您可以使用 GET 方法通过表单发送分页数量。视图可能会得到它。

一旦视图获得方法 GET 传递的数据(分页编号),它就会处理请求,然后它会给您一个响应,其中包括您应该在模板中呈现的分页数据。

<form method="GET">
    <select name="paginate_by" id="">
        <option value="10">10</option>
        <option value="20">10</option>
        <option value="30">30</option>
        <option value="50">50</option>
    </select>
    <input type="submit" value="Paginate">
</form>

<!-- RENDER YOU LIST HERE. Now context_object_name must be DataPaginated or whatever name you call it-->

<div class="pagination">
    <span class="step-links">
        {% if DataPaginated.has_previous %}
            <a href="?page=1&param={{param}}">&laquo; first</a>
            <a href="?page={{ DataPaginated.previous_page_number }}&param={{param}}">previous</a>
        {% endif %}

        <span class="current">
            Page {{ DataPaginated.number }} of {{ DataPaginated.paginator.num_pages }}.
        </span>

        {% if DataPaginated.has_next %}
            <a href="?page={{ DataPaginated.next_page_number }}&param={{param}}">next</a>
            <a href="?page={{ DataPaginated.paginator.num_pages }}&param={{param}}">last &raquo;</a>
        {% endif %}
    </span>
</div>
Run Code Online (Sandbox Code Playgroud)

Django 文档分页

.get_page

.get_page 方法是在 Django 2.0 中添加的。在旧版本上,您将需要

 try:
     paginated = paginator.page(page)
 except PageNotAnInteger:
     paginated = paginator.page(1)
 except EmptyPage:
     paginated = paginator.page(paginator.num_pages)
Run Code Online (Sandbox Code Playgroud)

您可以在执行此操作时检查您正在使用的版本manage.py runserver。就我而言,它是version 1.11.17.

(ECOMME~1) C:\Users\HP\EcommerceProject>python manage.py runserver

Django version 1.11.17, using settings 'EcommerceProject.settings'
Starting development server at http://127.0.0.1:8000/
Run Code Online (Sandbox Code Playgroud)