4
votes

I am using a Django Paginator and I want to have multiple available get parameters, such as: page=1 sort_by=price

However, in my template tags I have:

Showing items sorted by {{ SORT_PARAM }}.
Showing {{ ITEMS_PER_PAGE }} items per page.

{% if has_prev %}
<a href="?page={{ prev_page }}">Previous</a> |
{% endif %}

However, this does not preserve the other GET variables. What I mean is, if I'm viewing

page/?page=1&sort_by=price

and I click the link in the template fragment above, I will go to

page=2

instead of

page=2&sort_by=price

What I mean is, the a href does not preserve the other GET parameters.

One solution is I could type all the possible GET parameters in the a href, such as

<a href="?page={{ prev_page }}&items_per_page={{ ITEMS_PER_PAGE }}&sort_param={{ SORT_PARAM }}">Previous</a>

but this will become less scalable the more arguments I want to add to my browsing. I'm guessing there should be an automated way to obtain all GET parameters, and then pass those and one more?

3
try to create special template_tag: ie. {% pager_url page=page_no items_per_page=ITEMS_PER_PAGE sort_param=SORT_PARAM %} (btw. if you take some params (ie. ITEMS_PER_PAGE) from settings, you don't need to pass it explicitly)yedpodtrzitko
Thanks. That might be worth a shotuser1034697
This answer was the one for me. In Django2 you can use it as it is.Guillaume Lebreton

3 Answers

1
votes

You can create a 'parameter-string'. Let's supose that in your code you have:

my_view( request, page, options):
    sort_choices = {P:'price',N:'name', ...}
    n_item_choices = {'S':5, 'L':50, 'XL':100)
    ascending_descending_choices = {'A':'', 'D':'-'}
    ...

then you can concatenat options as:

options='P-S-D'  #order by price, 5 items per page, descending order

encode opions as:

<a href="?page={{ prev_page }}&options={{ options }}">Previous</a>

then, in urls.py capture options and in view:

my_view( request, page, options):
   ... #choides ....
   try:
      optionsArray = options.split('-')
      sort_by = sort_choices[ optionsArray[0]  ]
      n_ites_page = n_item_choices[ optionsArray[1]  ]
      asc_or_desc = ascending_descending_choices[ optionsArray[2]  ]
      ...
   except:
      somebody is playing ....

with this method you are free to add more paginations options without modify urls.py, all you need is to append options at the end of string options . This has advantages but also some dangers: I hope you can identify risks.

0
votes

With Django's Pagination - preserving the GET params is simple.

First copy the GET params to a variable (in view):

GET_params = request.GET.copy()

and send it to the template in via context dictionary:

return render_to_response(template,
                        {'request': request, 'contact': contact, 'GET_params':GET_params}, context_instance=RequestContext(request))

Second thing you need to do is use it specify it in the url calls (href) in the template - an example (extending the basic pagination html to handle extra param condition):

{% if contacts.has_next %}
    {% if GET_params %}
        <a href="?{{GET_params.urlencode}}&amp;page={{ contacts.next_page_number }}">next</a>
    {% else %}
        <a href="?page={{ contacts.next_page_number }}">next</a>
    {% endif %}
{% endif %}

Source - Posted same answer.