If I have applied the sorting to my wallpapers and after that if I try to paginate the sorting gets reset. like if I have sorted wallpapers according to pub date in ascending order and after pagination, it gets back to normal.
view
def home(request): WAllPAPER_PER_PAGE = 4 WALL = Wallpaper.objects.all() from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator import json from django.core.serializers.json import DjangoJSONEncoder from django.db.models import Q ordering =request.GET.get('ordering', "") search = request.GET.get('search', "") if search: wallpapers = Wallpaper.objects.filter(Q(name__icontains=search) | Q(category__category_name__icontains=search) | Q(tags__tag__icontains=search)) else: wallpapers = Wallpaper.objects.all() if ordering: wallpapers = wallpapers.order_by(ordering) page = request.GET.get('page', 1) wallpaper_paginator = Paginator(wallpapers, WAllPAPER_PER_PAGE) try: wallpapers = wallpaper_paginator.page(page) except EmptyPage: wallpapers = wallpaper_paginator.page(wallpaper_paginator.num_pages) except: wallpapers = wallpaper_paginator.page(WAllPAPER_PER_PAGE) context = {"wallpapers": wallpapers, 'page_obj': wallpapers, 'is_paginated': True, 'paginator': wallpaper_paginator, 'WALL': WALL} return render(request, "Wallpaper/Home.html", context)
Pagination code
{% if is_paginated %} <nav class="pagination" > <ul class="pagination" id="Pagination-list" > {% if page_obj.has_previous %} <li class="page-item" > <a class="page-link" tabindex="-1" aria-disabled="true" href="/?page={{ page_obj.previous_page_number }}">Previous</a> </li> {% endif %} {% for i in paginator.page_range %} {% if i == page_obj.number%} <li class="page-item active" aria-current="page"> <a class="page-link" href="/?page={{i}}" span class="visually-hidden">{{i}}</span></a> </li> {% else %} <li class="page-item" id="{{i}}" value="{{i}}"><a class="page-link" href="/?page={{i}}">{{i}}</a></li> {% endif %} {% endfor %} {% if page_obj.has_next %} <li class="page-item"> <a class="page-link" tabindex="-1" href="/?page={{ page_obj.next_page_number }}">Next</a> </li> {% endif %} </ul> </nav> {% endif %}
//Java script for searching and sorting sync function get(name) { if (name = (new RegExp('[?&]' + encodeURIComponent(name) + '=([^&]*)')).exec(location.search)) //location.search give query sling part return decodeURIComponent(name[1]); } if (get('ordering')) document.getElementById('placeholder').innerHTML = "Sort: " + document.getElementById(get('ordering')).innerHTML; if (get('page')) document.getElementById('Pagination-placeholder').innerHTML = "Pagination: " + document.getElementById(get('page')).innerHTML; function finalurl() { var url = new URL(window.location.href); console.log(url) var search_params = url.searchParams; console.log(search_params) search_params.set('ordering', document.getElementById("sort-list").value); url.search = search_params.toString(); var new_url = url.toString(); console.log(new_url) return new_url }
<!-- searching code --> <form method="GET" action="/" class="d-flex"> <input class="form-control me-2" name="search" id="search" type="search" placeholder="Search" aria-label="Search"> <button class="btn btn-outline-success" type="submit">Search</button> </form> <!-- sorting HTML code --> <select name="sort" id="sort-list" onchange="location = finalurl();" style="margin-left: auto;"> <option value="" id="placeholder" disabled selected hidden>sort</option> <option id="pub_date" value="pub_date">Recently added</option> <option id="-pub_date" value="-pub_date">old post</option> </select>
Advertisement
Answer
The reason this happens is because you “drop” the URL parameters regarding sorting and searching. You should each time add these to the pagination URLs.
In the view you can make a querystring for all the parameters except page with:
def home(request): qd = request.GET.copy() qd.pop('page', None) querystring = qd.urlencode() # … context = {'querystring': querystring, 'wallpapers': wallpapers, 'page_obj': wallpapers, 'is_paginated': True, 'paginator': wallpaper_paginator, 'WALL': WALL} return render(request, "Wallpaper/Home.html", context)
then in the template, you render the links to the other pages with:
<a href="/?page={{ page_obj.previous_page_number }}&{{ querystring }}" class="page-link" tabindex="-1" aria-disabled="true">Previous</a>
and this for all URL links.