Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change value for paginate_by on the fly

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?

like image 555
Al G Avatar asked Oct 31 '25 12:10

Al G


1 Answers

You don't need to override the get method, the correct way to do this is overriding the method 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)

Now you can filter: http://localhost:8000/videos/?paginate_by=40

Greetings.

like image 134
Víctor Villalobos Avatar answered Nov 04 '25 19:11

Víctor Villalobos



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!