Reputation: 1632
I'm using Django pagination, and everything is working fine except only one page is sorted.
What I have tried:
if request.method == 'POST':
if request.POST.get('sort_by') == 'price':
products_list = Product.objects.filter(category = category).order_by('price')
selected_sort_price = "selected"
elif request.POST.get('sort_by') == 'name':
products_list = Product.objects.filter(category = category).order_by('name')
selected_sort_name = "selected"
elif request.POST.get('sort_by') == 'date':
products_list = Product.objects.filter(category = category).order_by('-id')
selected_sort_date = "selected"
show=request.POST.get('show', 5)
else:
products_list=Product.objects.filter(category = category).order_by('-id')
...
page = request.GET.get('page', 1)
paginator = Paginator(products_list, show)
try:
products = paginator.page(page)
except PageNotAnInteger:
products = paginator.page(1)
except EmptyPage:
products = paginator.page(paginator.num_pages)
The above only works if there is post call, if no post call, then it is sorted by date of creation.
So if a user wants to sort by price, he will select price from a dropdown menu, and onchange
, form will be submitted and objects sorted accordingly. The problem is, when the user goes to second page, then everything goes back to default, because no post calls are made, and the previous post data isn't retained.
What can I do to make the sorting apply to all pages?
Looking for some direction,
Upvotes: 1
Views: 837
Reputation: 361
In your view, you should get the sort_by param using GET method and then, you can return the sort_by to the template for the next pages, you can try:
show=request.POST.get('show', 5)
sort_by = '-id'
if reques.GET.get('sort_by'):
if reques.GET.get('sort_by') in ['price', 'name', 'date']:
sort_by= request.GET.get('sort_by')
products_list = Product.objects.filter(category=category).order_by(sort_by)
paginator = Paginator(products_list, show)
page = request.GET.get('page', 1)
try:
products = paginator.page(page)
except PageNotAnInteger:
products = paginator.page(1)
except EmptyPage:
products = paginator.page(paginator.num_pages)
return render(request, 'my_template.html', {'products': products, 'sort_by': sort_by})
In your template, add the sort_by param to the previous/next page links:
{% for product in products %}
...
{% endfor %}
<div class="pagination">
<span class="step-links">
{% if products.has_previous %}
<a href="?sort_by={{ sort_by }}&page={{ products.previous_page_number }}">previous</a>
{% endif %}
<span class="current">
Page {{ products.number }} of {{ products.paginator.num_pages }}.
</span>
{% if contacts.has_next %}
<a href="??sort_by={{ sort_by }}&page={{ products.next_page_number }}">next</a>
{% endif %}
</span>
</div>
I hope this was useful.
Upvotes: 1
Reputation: 4213
like @Melvyn said you should work with GET method. Only use POST when you send sensitive information to the server or when you save data to it.
An example of get method should be:
if reques.GET.get('sort_by'):
prince = request.GET.get('sort_by')
products_list = Product.objects.filter(category = category).order_by(price)
selected_sort_price = "selected"
I don't have enough information of your project so I cant help you. Anyway tell me if that work.
Upvotes: 1