#StackBounty: #django #django-filter #django-pagination Paginate a filter

Bounty: 50

I have a filter with a dependent drop down for cars makes and models. Since I don’t want to display all of them on one page I added a paginator. The issue is the filter works correctly but it does not carry over in the pages

when the filter is active the url looks like

/cars/?manufacture=2&model=2
If i go to the next page all I get is /cars/?page=2

I want something like /cars/?manufacture=2&model=2?page=2

If I print {{ posts|length }} it does return the proper number of items that are being filtered so there is not issue there

I believe the issue is with the next and previous buttons in the template as they don’t pass any parameters in them other then next page. How do i carry the filter into the paginator.

view

def allCarsView(request):

    model = Post
    
    myFilter = carFilter(request.GET, queryset=Post.objects.all())
    posts = myFilter.qs
    
    page = request.GET.get('page', 1)
    paginator = Paginator(posts.order_by('date_posted'), 2)
    page_obj = paginator.get_page(page)
    page_range = paginator.get_elided_page_range(number=page)
    
    context = {
        'posts':posts, 'myFilter':myFilter, 'page_range': page_range, 
        'page': page, 'paginator': paginator, 'page_obj': page_obj
    }
    return render(request, 'blog/cars.html', context)    

Paginator html

<nav aria-label="Page navigation example " class="paginator">
<nav aria-label="Page navigation example " class="paginator">
    <ul class="pagination justify-content-center">
        <li class="page-item">
            {% if page_obj.has_previous %}
            <a class="page-link" href="?page={{ page_obj.previous_page_number }}" aria-label="Previous">
                <span aria-hidden="true">&laquo;</span>
            </a>
            {% else %}
        </li>

        <li class="page-item disabled">
            <a class="page-link" href="#" aria-label="Previous">
                <span aria-hidden="true">&laquo;</span>
            </a>
        </li>
        {% endif %} {% for i in page_obj.paginator.page_range %} {% if page_obj.number == i %}
        <li class="page-item active" aria-current="page">
            <a class="page-link" href="#">{{ i }}</a>
        </li>
        {% elif i > page_obj.number|add:'-3' and i < page_obj.number|add:'3' %}
        <li class="page-item"><a class="page-link" href="?page={{ i }}">{{ i }}</a></li>
        {% endif %} {% endfor %}

        <li class="page-item">
            {% if page_obj.has_next %}
            <a class="page-link" href="?page={{ page_obj.next_page_number }}" aria-label="Previous">
                <span aria-hidden="true">&raquo;</span>
            </a>
            {% else %}
        </li>

        <li class="page-item disabled">
            <a class="page-link" href="#" aria-label="Previous">
                <span aria-hidden="true">&raquo;</span>
            </a>
        </li>
        {% endif %}
    </ul>
</nav>

Update:
From doing more research it does seem that my issue is with the urls in the paginator as they do not carry any parameters. There does not seem to be a best way to do this and the solutions I have tried have yielded nothing.

Update:
Attempting to use this post as the solution

view (added under previous code)
from django import template
register = template.Library()

@register.simple_tag
def url_replace(request, field, value):

    dict_ = request.GET.copy()

    dict_[field] = value

    return dict_.urlencode()

template:

<a class="page-link" href="?{% url_replace request 'page' page_obj.next_page_number %}" aria-label="Previous">

I then get the error

Invalid block tag on line 88: 'url_replace', expected 'elif', 'else' or 'endif'. Did you forget to register or load this tag?

so at the top if I add

{% load url_replace %}

throws the error

'url_replace' is not a registered tag library


Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.