I use the code from the documentation to paginate the data:

try:
    data = paginator.page(request.GET.get('page'))
except PageNotAnInteger:
    page = 1
    data = paginator.page(1)
except EmptyPage:
    data = paginator.page(paginator.num_pages)

And a page:

<div class="pagination">
      <span class="step-links">
          {% if data.has_previous %}
              <a href="?page={{ data.previous_page_number }}">previous</a>
          {% endif %}

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

          {% if data.has_next %}
              <a href="?page={{ data.next_page_number }}">next</a>
          {% endif %}

      </span>
    </div>

But there's a bug here: when the url contains a query string and one clicks on the Pager, the original query string gets lost. For example:

example.com?var1=33&var2=44

and then when one clicks on "page2", the url becomes

example.com?page=2  # var1=33&var2=44 is lost

instead of:

example.com?var1=33&var2=44&page=2 

I haven't found neither the standard, nor easy way to fix it. How can I do that?

UPDATE:

of course, the names of the parameters, their values and whether they exist or not is not known.

3 Answers

10
Julien Grégoire On Best Solutions

You can access parameters from your request directly in your template if you activate django.core.context_processors.request in your settings. See https://docs.djangoproject.com/en/1.7/ref/templates/api/#django-core-context-processors-request

Then you can access parameters in your template directly. In your case you'll need to filter page parameter. You could do something like this:

href="?page={{ data.next_page_number }}{% for key, value in request.GET.items %}{% if key != 'page' %}&{{ key }}={{ value }}{% endif %}{% endfor %}"
0
YPCrumble On

The easy way would be to include those variables in your template:

<a href="?var1={{var1}}&var2={{var2}}&page={{ data.next_page_number }}">next</a>

Just add var1 and var2 to your context.

That's if the query string variables are originated from your backend. If they're coming from the front-end/external, you could use something like How can I get query string values in JavaScript? in your template and either edit the template vars directly or pass the values to your backend.

6
prokaktus On

Another possible solution can be to construct parameters list in your view. Pros: you can use clean and expressive methods on QueryDict.

It will be look like this:

get_copy = request.GET.copy()
parameters = get_copy.pop('page', True) and get_copy.urlencode()
context['parameters'] = parameters

That's it! Now you can use your context variable in template:

 href="?page={{ paginator.next_page_number }}&{{ parameters }}" 

See, code looks clean and nicely.

note: assumes, that your context contained in context dict and your paginator in paginator variable