How do I keep all query parameters intact when changing page in django?

57 views Asked by At

I have this issue with pagination:

<a href="{{ request.get_full_path }}{% if request.GET %}&{% else %}?{% endif %}page={{ page_obj.previous_page_number }}">previous</a>

It works fine, but every time I click on it it adds one more ?page=1 at the end of the URL, so url looks like this after a few clicks: example/something?query_params=5&page=1&page=1&page=1&page=1

I know why that happens, it's because I hardcoded it into URL, but I have to use get_full_path because I need other query parameters together with page.

So basically I want all those query params but WITHOUT page=something being added each time I change the page. I need only one page query parameter.

1

There are 1 answers

2
willeM_ Van Onsem On BEST ANSWER

You can effectively remove the page number in the view, like:

class MyView(View):
    # …

    def request_get(self):
        rq = self.request.GET.copy()
        rq.pop(self.page_kwarg, None)
        return rq.urlencode()

then in the view, we can work with:

<a href="{{ request.path }}?{{ view.request_get }}&amp;page={{ page_obj.previous_page_number }}">previous</a>

we can also make a helper function for this to include the path:

class MyView(View):
    # …

    def request_get(self):
        rq = self.request.GET.copy()
        rq.pop(self.page_kwarg, None)
        return rq.urlencode()

    def path_without_page(self):
        return f'{self.request.path}?{self.request_get()}'

and thus work with:

<a href="{{ view.path_without_page }}&amp;page={{ page_obj.previous_page_number }}">previous</a>

It is however a bit of a pity that the page object itself has no access to the request object, and that thus the pager could construct such links. I personally find this one of the shortcomings of Django's pagination system.