动态更改 paginate_by 的值 [英] Change value for paginate_by on the fly

查看:22
本文介绍了动态更改 paginate_by 的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够允许用户更改默认页面大小 (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):查询集 = Proddetails.objects.all()serializer_class = ProdSerializer类 ProdListView(ListView):型号 = 产品详情模板名称 = 'prod_list.html'# 为分页添加context_object_name = 'prods' #默认值:object_listpaginate_by = 10

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

谢谢--

阿尔

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

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

{% for i in DataPaginated.paginator.page_range %}{% if DataPaginated.number == i %}<button class="w3-button w3-amber">{{ i }} </button>{% 别的 %}<a href="?page={{ i }}" class="w3-button">{{ i }}</a>{% 万一 %}{% 结束为 %}

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

解决方案

from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage类 ProdListView(ListView):型号 = 产品详情模板名称 = 'prod_list.html'# 为分页添加context_object_name = 'prods' #默认值:object_listpaginate_by = 10def get(self, request):paginate_by = request.GET.get('paginate_by', 10) 或 10数据 = self.model.objects.all()paginator = Paginator(data, paginate_by)page = request.GET.get('page')尝试:分页 = paginator.get_page(page)除了 PageNotAnInteger:分页 = paginator.get_page(1)除了 EmptyPage:分页 = paginator.page(paginator.num_pages)返回渲染(请求,self.template_name,{'DataPaginated':分页,'paginate_by':paginate_by})

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

一旦视图获得方法 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></选择><输入类型=提交"值=分页"></表单><!-- 在此处呈现您的列表.现在 context_object_name 必须是 DataPaginated 或您称之为的任何名称--><div class="分页"><span class="step-links">{% if DataPaginated.has_previous %}<a href=?page=1&param={{param}}">&laquo;首先<a href="?page={{ DataPaginated.previous_page_number }}&param={{param}}>previous</a>{% 万一 %}<span class="current">第 {{ DataPaginated.number }} 页,共 {{ 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>{% 万一 %}</span>

Django 文档分页

.get_page

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

 尝试:分页 = paginator.page(page)除了 PageNotAnInteger:分页 = paginator.page(1)除了 EmptyPage:分页 = paginator.page(paginator.num_pages)

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

(ECOMME~1) C:UsersHPEcommerceProject>python manage.py runserverDjango 版本 1.11.17,使用设置EcommerceProject.settings"在 http://127.0.0.1:8000/启动开发服务器

I would like to be able to allow users change the default page size (paginate_by). My current page size is set to 10; I'd like to have buttons for say 25, 50, and all.

I am running Django 2.2 and Python 3.73 with postgresql 11.4. My views.py creates a queryset and sets up pagination. My prod_list.html template properly displays the data in pages with ten rows per page.

Here is what I currently have in my 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

I want to be able to let my users change the number of rows per page. I'm thinking I need to reset paginate_by based on which button the user clicks, but how can I do that?

Thanks--

Al

Well, I tried to comment, but that didn't give me enough room. I hope this is the correct way to do this:

Thank you very much; that did the trick. I modified it to give me buttons with the page numbers, though, and I'm getting an odd behavior. I have a for loop that I use to put out the page numbers as buttons:

{% 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 %}

If the pagination is set to the default of ten this works properly and shows three pages (there are 24 items). If I change the pagination to 20, it looks right at first and shows two pages. However, if I click on the second page, it changes my pagination back to 10, shows three pages again, and places me on the 2nd of the three pages. Is there something I can do to keep my pagination locked at the setting chosen with the form?

解决方案

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})

you should put this in your template to allow to the user to select the pagination. you may send the number of paginate by the form using the method GET. the view may get it.

once the view get the data (paginate number) passed by method GET it process the request then it give you a response that include the paginate data you should render in the template.

<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>

Django Documentation Pagination

.get_page

The .get_page method was added in Django 2.0. On older versions you will need

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

You can check what version you are using when you do manage.py runserver. In my case it is version 1.11.17.

(ECOMME~1) C:UsersHPEcommerceProject>python manage.py runserver

Django version 1.11.17, using settings 'EcommerceProject.settings'
Starting development server at http://127.0.0.1:8000/

这篇关于动态更改 paginate_by 的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆