I have successfully paginated when returning all the objects but however, when I query the return for the searched result, it initially gets the correct pagination number of page. But clicking on any of the paginated searched result will immediately return the pagination of all the objects.
My HTML pagination
<ul class="pagination center" id="pagination" hx-swap-oob="true">
{% if data.has_previous %}
<li class="waves-effect">
<a href="?page={{ data.previous_page_number }}"><i class="material-icons"><</i></a>
</li>
{% endif %} {% for page in data.paginator.page_range %} {% if page == data.number %}
<li class="active purple lighten-2"><a href="?page={{ page }}">{{page}}</a></li>
{% else %}
<li class="waves-effect"><a href="?page={{ page }}">{{page}}</a></li>
{% endif %} {% endfor %} {% if data.has_next %}
<li class="waves-effect">
<a href="?page={{data.next_page_number}}"><i class="material-icons">></i></a>
</li>
{% endif %}
</ul>
paginate function and views.py, when i use AI, it shows me to change the html code, but i cannot understand it and i've spent hours to find something that mentions this very well and haven't found one
def paginate(data, request):
paginator = Paginator(data, 10)
page_number = request.GET.get('page')
data = paginator.get_page(page_number)
return data
def submission_portal(request):
data = DataEntry.objects.all()
data = paginate(data=data, request=request)
text_count = DataEntry.objects.filter(category='text').count()
image_url_count = DataEntry.objects.filter(category='image_url').count()
context = {
'data': data,
'text_count': text_count,
'image_url_count': image_url_count
}
return render(request, 'submission_portal/submission_page.html', context=context)
# Read https://www.w3schools.com/django/django_queryset_filter.php
# Search Bar Handler
def form_search(request):
if request.method == 'POST':
data = DataEntry.objects.filter(content__contains=request.POST.get('search'))
data = paginate(data=data, request=request)
context = {
'data': data
}
return render(request, 'submission_portal/components/pagination.html', context=context)
The search query parameters are not being preserved when you navigate through the pagination links. When you click on a pagination link, it only includes the page
parameter in the URL, but not the search query that was used to filter the results initially.
you should include the search query in the pagination links so that it persists across different pages of the search results.
First of all, update the form_search
view to pass the search query to the template:
def form_search(request):
if request.method == 'POST':
search_query = request.POST.get('search')
data = DataEntry.objects.filter(content__contains=search_query)
data = paginate(data=data, request=request)
context = {
'data': data,
'search_query': search_query # Pass the search query to the template
}
return render(request, 'submission_portal/components/pagination.html', context=context)
Then update the html pagination code to include the search query in the pagination links:
<ul class="pagination center" id="pagination" hx-swap-oob="true">
{% if data.has_previous %}
<li class="waves-effect">
<a href="?page={{ data.previous_page_number }}&search={{ search_query }}"><i class="material-icons"><</i></a>
</li>
{% endif %}
{% for page in data.paginator.page_range %}
{% if page == data.number %}
<li class="active purple lighten-2"><a href="?page={{ page }}&search={{ search_query }}">{{page}}</a></li>
{% else %}
<li class="waves-effect"><a href="?page={{ page }}&search={{ search_query }}">{{page}}</a></li>
{% endif %}
{% endfor %}
{% if data.has_next %}
<li class="waves-effect">
<a href="?page={{data.next_page_number}}&search={{ search_query }}"><i class="material-icons">></i></a>
</li>
{% endif %}
</ul>
If you want to handle the search query in the submission_portal
view as well (in case the user submits the search form via GET request), you can modify it like this:
def submission_portal(request):
search_query = request.GET.get('search', '')
if search_query:
data = DataEntry.objects.filter(content__contains=search_query)
else:
data = DataEntry.objects.all()
data = paginate(data=data, request=request)
text_count = DataEntry.objects.filter(category='text').count()
image_url_count = DataEntry.objects.filter(category='image_url').count()
context = {
'data': data,
'text_count': text_count,
'image_url_count': image_url_count,
'search_query': search_query # Pass the search query to the template
}
return render(request, 'submission_portal/submission_page.html', context=context)
(As @mariodev said in comments), to show the search query in the url (which is necessary for pagination to work correctly), you should use the GET method in your search form:
<form method="get" action="{% url 'submission_portal' %}">
<input type="text" name="search" placeholder="Search..." value="{{ search_query }}">
<button type="submit">Search</button>
</form>