0

Trying to get pagination to work in Django. It looks fine on page 1 but when I go to page 2, I can see my entire database is shown.

This is my code:

class AdvancedSearch(ListView):
        template_name= 'saferdb/AdvancedQuery.html'

        def get(self, request):
            c = request.GET.getlist('opeclass')
            q = Question.objects.all()

            #Ugly q filtering methods

            paginator = Paginator(q, 25)
            page = request.GET.get('page')
            contacts = paginator.get_page(page)
            return render(request, 'saferdb/list.html', {'text' : count , 'contacts': contacts})

URLS.py

urlpatterns = [
    url(r'^$', views.index, name='index'),
    url(r'^query/$', views.QueryView.as_view(), name='query'),
    url(r'^advanced/$', views.AdvancedSearch.as_view(), name='advanced'),
]

template code:

<form method="get">

<!--- bunch of selection to filer output by --->
<div class="pagination">
    <span class="step-links">
        {% if contacts.has_previous %}
            <a href="?page=1">&laquo; first</a>
            <a href="?page={{ contacts.previous_page_number }}">previous</a>
        {% endif %}

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

        {% if contacts.has_next %}
            <a href="?page={{ contacts.next_page_number }}">next</a>
            <a href="?page={{ contacts.paginator.num_pages }}">last &raquo;</a>
        {% endif %}
    </span>
</div>
Lev
  • 999
  • 2
  • 10
  • 26

1 Answers1

1

If you use def get method, you should`t use ListView, use TemplateView or View instead. ListView has paginate_by attr, for instance

class AdvancedSearch(ListView):
    template_name= 'saferdb/AdvancedQuery.html'
    paginate_by=25
    page_kwarg = 'page'

page_kwarg == 'page' by default and it checks your url and get data for page_kwarg value, so what you can do with ListView is this

class AdvancedSearch(ListView):
    template_name= 'saferdb/AdvancedQuery.html'
    paginate_by=25
    context_object_name = 'contacts'
    model = Question

    def get_queryset(self):
        c = self.request.GET.getlist('opeclass')
        q = Question.objects.all()
        ...
        return queryset

    def get_context_data(self, **kwargs):
        context = super(AdvancedSearch, self).get_context_data(**kwargs)
        context.update({...})
        return context             

that actually it

P.S. For my point of view, it's a little bit strange, that you paginate by Question model queryset but in the response queryset is called contacts. Probably, something important missed here in your code?

Basalex
  • 1,147
  • 9
  • 20
  • Used your solution to figure it out. Created a global variable that saved the query parameters and passed it to the pagination function. Thanks – Lev Feb 18 '18 at 04:39