0

In a Django CBV (ListView), after submitting a form using GET method, with filter_1 and filter_2 fields, the resulting URL I get is something like:

http://example.com/order/advanced-search?filter_1=foo&filter_2=bar

Everything is ok. However, I'd like to use pagination, proving to my template a URL like:

http://example.com/order/advanced-search?page=2&filter_1=foo&filter_2=bar

Let's say I could override this method for this purpose:

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    context['my_form_values'] = self.request.GET

Now, how can I use my_form_values in my pagination template to display the right URLs?

For now, here is my (simplified) pagination template code:

{% for num in page_obj.page_range %}
    {% if page_obj.number == num %}
        <li class="page-item active">
            <span class="page-link">{{ num }}</span>
        </li>
    {% else %}
        <li class="page-item">
            <a class="page-link" href="?page={{ num }}">{{ num }}</a>
        </li>
    {% endif %}
{% endfor %}
David Dahan
  • 10,576
  • 11
  • 64
  • 137
  • 3
    The problem with `?page={{num}}` is that you've lost the rest of the filters (e.g. `filter_1=foo`). [Here's a template tag](https://gist.github.com/etchalon/4493752) that might be useful. I found it by searching *django querydict template tag*, I'm sure I've seen others in the past as well. – Alasdair Feb 21 '19 at 13:27
  • @Alasdair `href="?page={{ num }}&{% qs_alter request.GET -page %}"` is almost working. The only issue is that `page` parameter is not removed and is stacked. In the end, I got something like: `?page=3&page=4&filter_1=foo&filter_2=bar` – David Dahan Feb 21 '19 at 13:47
  • replacing `k, v = arg.split("-", 2)` (makes no sense because the key would be empty) with `_, k = arg.split("-", 2)` works ... I'm not sure I understood how to use this template tag actually. – David Dahan Feb 21 '19 at 14:07
  • From the [examples](https://gist.github.com/etchalon/4493752#file-gistfile1-py-L42), I think you want `?{% qs_alter request.GET page=num %}`, but if that doesn't work, I'm afraid I can't help you debug it because I haven't used that tag before. You might find it easier to search for a similar tag - I only included it as an example of the type of thing I've seen before. – Alasdair Feb 21 '19 at 14:50
  • Thanks it works as expected with `{% qs_alter request.GET page=num %}`. Please consider writing an answer so that I accept it :) – David Dahan Feb 22 '19 at 10:20

1 Answers1

1

I do it this way

@register.simple_tag(takes_context=True)
def param_replace(context, **kwargs):
    d =context['request'].GET.copy()
    for k,v in kwargs.items():
        d[k] = v
    for k in [k for k,v in d.items() if not v]:
        del d[k]
    return d.urlencode()

and then the pagination in template

<ul class="pagination">
    {% if page_obj.has_previous %}
        <li class="page-item"><a class="page-link"
                                 href="?{% param_replace page=1 %}">{% trans 'first' %}</a>
        </li>
        <li class="page-item"><a class="page-link"
                                 href="?{% param_replace page=page_obj.previous_page_number %}">{{ page_obj.previous_page_number }}</a>
        </li>
    {% endif %}
    <li class="page-item active"><a class="page-link"
                                    href="?{{ page_obj.number }}">{{ page_obj.number }}</a>
    </li>
    {% if page_obj.has_next %}
        <li class="page-item"><a class="page-link"
                                 href="?{% param_replace page=page_obj.next_page_number %}">{{ page_obj.next_page_number }}</a>
        </li>
        <li class="page-item"><a class="page-link"
                                 href="?{% param_replace page=page_obj.paginator.num_pages %}">{% trans 'last' %}</a>
        </li>
    {% endif %}
</ul>
pfitzer
  • 76
  • 5