Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Paginate a filter

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

Attempt at being able to select page number from paginator

            {% elif i > page_obj.number|add:'-3' and i < page_obj.number|add:'3' %}
            {% if page_obj.number > i  %}
                <li class="page-item"><a class="page-link" href="?{% querystring_replace request 'page' page_obj.previous_page_number %}">{{ i }}</a></li>    
            {% endif %}
            {% if page_obj.number < i  %}
                <li class="page-item"><a class="page-link" href="?{% querystring_replace request 'page' page_obj.next_page_number %}">{{ i }}</a></li>    
            {% endif %}
        {% endif %} {% endfor %}
like image 854
Wazy Avatar asked Aug 17 '21 16:08

Wazy


People also ask

What is API pagination?

Pagination turns big archives of data into smaller, more digestible pieces. Clicking through an archive of pictures, or turning the page of a book, are examples of pagination.

Why do we paginate data?

Pagination thus helps to limit the number of results to help keep network traffic in check.

What does it mean to paginate data?

Pagination is the process of separating print or digital content into discrete pages. For print documents and some online content, pagination also refers to the automated process of adding consecutive numbers to identify the sequential order of pages.

How would you implement pagination with filter in react?

How can i implement pagination with filter? Conceptually, what you'd do is filter FIRST. Store those in a state somewhere. Then use that filtered list as your datasource and page THAT.

How to do pagination and filtering in DataTables using SQL?

Depending on its length, we either add an additional WHERE products.name LIKE '%filter%' condition to our SQL or not. You can enter some product name or part of it and click Filter to select only the products with the name LIKE the filter. DataTables is a JavaScript library which can do pagination, sorting and filtering out of the box.

When to use offset paging vs keyset pagination?

Even with limitations, offset paging is easy to implement and understand and can be used in applications where the data set has a small upper bounds. Keyset pagination uses the filter values of the last page to fetch the next set of items. Those columns would be indexed. Client makes request for most recent items: GET /items?limit=20

Is there any API design guide for Advanced Filtering and pagination?

However, there is no standard or official API design guidelines. RESTful is only an architectural style. There are many beginner api-guide for API design readily available such as this guide and this guide . However, we didn’t find many api-guide on more advanced filtering and pagination, which inspired us to publish this post.

How to paginate a product model?

assume you need to paginate your Product models. You can add the following controller action: You can see that we call paginate () on the Product model and pass it the page size (5). This method automatically reads the request and gets the page query parameter from it. This allows it


1 Answers

This can be done using custom template tags as shown in this answer. However, that answer skips over the whole process of creating custom tags, so let me show you how to do that.

Django requires that your custom tags be kept in a folder called templatetags inside an app. So this is what your app's folder structure must look like:

my-app/
├─ __ini__.py
├─ models.py
├─ views.py
├─ templatetags/
│  ├─ __init__.py
│  ├─ myapp_tags.py

Tip: You can also create a new app specifically for keeping custom tags. That way it becomes easy to re-use them in different projects. Make sure your new app is in INSTALLED_APPS list.

Now open the myapp_tags.py file and create the custom tag there:

# myapp_tags.py

from django import template

register = template.Library()

@register.simple_tag
def querystring_replace(request, key, value):
    """Replace the given `key` with the given `value`
    in the request's querystring. The rest of the
    querystring remains unchanged.
    """
    query_dict = request.GET.copy()
    query_dict[key] = value
    return query_dict.urlencode()

To use this tag in the templates, you'll need to load the file containing the tags:

 <!-- load the file containing the tags -->
{% load myapp_tags %}

<!-- now you can use all the tags from myapp_tags -->
{% querystring_replace request 'page' page_obj.next_page_number %}
like image 161
xyres Avatar answered Oct 24 '22 00:10

xyres