Reputation: 137
I have an issue when trying to use pagination after filtering. I make a search form in forms. In the first page, after searching the app show all contracts with conditions, however when I click page 2, it refreshes and shows other results. If I rewrite in search form, it will show the others result in page 2 in my form.py
class ContractSearchForm(forms.ModelForm):
use_required_attribute = False
export_to_CSV = forms.BooleanField(required=False)
class Meta:
model = Contracts
fields = ["contract","name"]
in my view.py
def list_contract(request):
header= "LIST OF CONTRACT"
form = ContractSearchForm(request.POST or None)
queryset =Contracts.objects.all()
#pagination
paginate_by = 10
paginate_by = request.GET.get('paginate_by', paginate_by) or 10
user_list = queryset
paginator = Paginator(user_list, paginate_by)
page = request.GET.get('page',1)
try:
queryset = paginator.page(page)
except PageNotAnInteger:
users = paginator.page(1)
except EmptyPage:
users = paginator.page(paginator.num_pages)
context = {
"form":form,
"header": header,
"queryset": queryset1,
'paginate_by':paginate_by,
}
if request.method == 'POST':
#Tạo queryset sang filter
queryset2 = Contracts.objects.filter(contract__icontains=form['contract'].value(),
name__icontains=form['name'].value().upper()
)
#pagination when search
paginate_by = 10
paginate_by = request.GET.get('paginate_by', paginate_by) or 10
user_list = queryset
paginator = Paginator(user_list, paginate_by)
page = request.GET.get('page',1)
try:
queryset = paginator.page(page)
except PageNotAnInteger:
users = paginator.page(1)
except EmptyPage:
users = paginator.page(paginator.num_pages)
context = {
"form":form,
"header": header,
"queryset": queryset,
'paginate_by':paginate_by,
}
return render (request, "customer1.html",context)
in customer1.html
{% if queryset.has_previous %}
<a href="?{% param_replace page=1 %}">First</a>
{% if queryset.previous_page_number != 1 %}
<a href="?{% param_replace page=queryset.previous_page_number %}">Previous</a>
{% endif %}
{% endif %}
Page {{ queryset.number }} of {{ queryset.paginator.num_pages }}
{% if queryset.has_next %}
{% if queryset.next_page_number != queryset.paginator.num_pages %}
<a href="?{% param_replace page=queryset.next_page_number %}">Next</a>
{% endif %}
<a href="?{% param_replace page=paginator.num_pages %}">Last</a>
{% endif %}
my ulr.py
urlpatterns = [
path('admin/', admin.site.urls),
path('demo',views.showDemoPage),
path('', include('test_upload_filter.urls')),
path('add_items/', views.add_items, name='add_items'),
path('contract_detail/<str:contract_id>/', views.contract_detail, name="contract_detail"),
in my app url.py
app_name='example_app'
urlpatterns = [
path("customer1/",page,name="list_contract")
]
I updated my code, I use template tag my_tags.py
@register.simple_tag(takes_context=True)
def param_replace(context, **kwargs):
d = context['request'].GET.copy()
for k, v in kwargs.items():
d[k] = v
for k in [k for k, v in d.items() if not v]:
del d[k]
return d.urlencode()
I try use django-filter with paginations but django-filter cannot distinguish upper and lower case.
My url browser is still the same after and before searching 127.0.0.1:8000/customer1
, in page 2 http://127.0.0.1:8000/customer1/?page=2
Thanks for your reading. Sorry because my code in view is too long because I have to rewrite two times pagination function.
Upvotes: 1
Views: 574
Reputation: 21
I don't know if this helps. I had a similar problem and just adapted the pagination urls:
<div id="pagelinks">
{% if ideas.has_previous %}
<a class="infinite-more-link" href="{{ request.get_full_path }}&page={{ ideas.previous_page_number }}" style="float:left;"><- Previous ideas<a>
{% endif %}
{% if ideas.has_next %}
<a class="infinite-more-link" href="{{ request.get_full_path }}&page={{ ideas.next_page_number }}" style="float:right;">More ideas -></a>
{% endif %}
</div>
JavaScript:
<script> function Waypoint(){ var infinite = new Waypoint.Infinite({ element: $('.infinite-container')[0] }); } </script>
Upvotes: 2
Reputation: 2102
use your own views.py
then you need to build a template tag in 'your_app_name/templatetags/my_tags.py' root like below code
my_tags.py
from django import template
register = template.Library()
@register.simple_tag(takes_context=True)
def param_replace(context, **kwargs):
d = context['request'].GET.copy()
for k, v in kwargs.items():
d[k] = v
for k in [k for k, v in d.items() if not v]:
del d[k]
return d.urlencode()
finally use that templatetag in in your template pagination:
html file
(don't forget to load your tag first)
notice where i'm using param_replace
{% load my_tags %}
.
.
.
.
<!-- Pagination -->
<nav aria-label="Page navigation">
{% if queryset.has_other_pages %}
<ul class="pagination justify-content-center">
{% if queryset.has_previous %}
<li class="page-item disabled">
<a class="page-link page-link-prev" href="{% url 'url_app_name:current_path_url_name' %}?{% param_replace page=queryset.previous_page_number %}" aria-label="Previous" tabindex="-1" aria-disabled="true">
<span aria-hidden="true"><i class="icon-long-arrow-left"></i></span>Previous
</a>
</li>
{% endif %}
{% for i in queryset.paginator.page_range %}
{% if queryset.number == i %}
<li class="page-item active" aria-current="page"><a class="page-link" href="#">{{ i }}</a></li>
{% else %}
<li class="page-item"><a class="page-link" href="?{% param_replace page=i %}">{{ i }}</a></li>
{% endif %}
{% endfor %}
{% if queryset.has_next %}
<li class="page-item">
<a class="page-link page-link-next" href="{% url 'url_app_name:current_path_url_name' %}?{% param_replace page=queryset.next_page_number %}" aria-label="Next">
Next<span aria-hidden="true"><i class="icon-long-arrow-right"></i></span>
</a>
</li>
{% endif %}
</ul>
{% endif %}
</nav>
<!-- Pagination -->
.
.
.
let me know if this worked for you
i can give you full working code that i'm using for myself for multiple filtering with pagination that you want
sorry for bad EN (:
Upvotes: 0