Django paginator page range for not displaying all numbers - python

I have a pagination in my site but it shows me every page like 1-19, i only want to display only 5 pages.
How can i do this?
views.py
paginator = Paginator(object_list, new_number_of_list)
page = request.GET.get('page')
try:
Items = paginator.page(page)
except PageNotAnInteger:
Items = paginator.page(1)
except EmptyPage:
Items = paginator.page(paginator.num_pages)
variables = RequestContext(request, {"Items": Items,
"ForItemCount": ForItemCount,
"page": page,
})
return render(request, 'templates/Core/resource_base.html',
variables)
my pagination.html
<div class="pagination p1">
<span class="step-links">
<ul>
{% for l in Items.paginator.page_range %}
<li>{{forloop.counter}}</li>
{% endfor %}
</ul>
</span>
</div>

Another quick solution that can be used(+ and - 5 limit for example):
{% for l in Items.paginator.page_range %}
{% if l <= Items.number|add:5 and l >= Items.number|add:-5 %}
<li>{{forloop.counter}}</li>
{% endif %}
{% endfor %}

You already have the {{ forloop.counter }} in there, you can use that to limit it to five.
{% for l in Items.paginator.page_range %}
{% if forloop.counter < 5 %}
<li>{{forloop.counter}}</li>
{% endif %}
{% endfor %}
Here is another solution, which might give you some more options if you're interested: Django Pagination Display Issue: all the page numbers show up.
And finally, here is a very nice tutorial on getting up to speed with the pagination that django offers out of the box: https://simpleisbetterthancomplex.com/tutorial/2016/08/03/how-to-paginate-with-django.html.

See if https://medium.com/#sumitlni/paginate-properly-please-93e7ca776432 helps. The code uses 10 for "neighbors" but you could change it to 5 when using the tag.

Related

Pagination in Django not working as expected

I wanted pagination for all the courses available and that was easy to achieve. But now I'm stuck because I wanted pagination for faculties also, which will show specific courses of the accessed faculty. I have 4 models: faculties, departments, studies, and courses. The pagination will show for faculties as well, but the problem is that if I try to go to the second page, it will redirect me to the second page of all courses list. Or, if I change page on all courses and then try to access a faculty, no course will show at all in the faculty.
def index(request):
course_list = Course.objects.all()
page = request.GET.get('page', 1)
paginator = Paginator(course_list, 1)
try:
courses = paginator.page(page)
except PageNotAnInteger:
courses = paginator.page(1)
except EmptyPage:
courses = paginator.page(paginator.num_pages)
faculty_list = Faculty.objects.all()
page = request.GET.get('page2', 1)
paginator = Paginator(faculty_list, 1)
try:
faculties = paginator.page(page)
except PageNotAnInteger:
faculties = paginator.page(1)
except EmptyPage:
faculties = paginator.page(paginator.num_pages)
context = {'courses': courses,
'faculties': faculties,
'departments': Department.objects.all(),
'studies': StudyProgramme.objects.all(),
'teachers': Teacher.objects.all()
}
return render(request, 'courses/index.html', context)
<div id="crs">
<h3>All courses</h3>
<ul>
{% for course in courses %}
<li><a href={{ course.slug }}>{{ course.name }}</a></li>
{% endfor %}
</ul>
<div class="pagination">
<span class="step-links">
{% if courses.has_previous %}
« first
{{ courses.previous_page_number }}
{% endif %}
<span class="current">
Page {{ courses.number }} of {{ courses.paginator.num_pages }}
</span>
{% if courses.has_next %}
{{ courses.next_page_number }}
last »
{% endif %}
</span>
</div>
</div>
{% for faculty in faculties %}
<div id="fac_{{ faculty.pk }}_tab" style="display:none;">
<h3> {{ faculty.name }} Courses</h3>
<ul>
{% for department in faculty.department_set.all %}
{% for study in studies %}
{% if study.department == department %}
{% for course in courses %}
{% if course.study_programme == study %}
<li>
<a class="first" href={{ course.slug }}>{{ course.name }}</a>
</li>
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% endfor %}
</ul>
<div class="pagination">
<span class="step-links">
{% if faculties.has_previous %}
« first
{{ faculties.previous_page_number }}
{% endif %}
<span class="current">
Page {{ faculties.number }} of {{ faculties.paginator.num_pages }}
</span>
{% if faculties.has_next %}
{{ faculties.next_page_number }}
last »
{% endif %}
</span>
</div>
</div>
{% endfor %}
It's not a Django problem that your view is most certainly handle one pagination parameter page which will direct to courses, so if you changed the get parameter for each of your model pagination it will work.
ex:
## views.py
page = request.GET.get('page')
## yourtemplate.html
yourtext
localhost:8000/MYVIEW/?page=2 # Goes to courses
## views.py
page = request.GET.get('faculties')
## yourtemplate.html
yourtext
##
localhost:8000/MYVIEW/?faculties=2 # Goes to faculties
etc..
edited:
{% for faculty in faculties %} change it to {% for faculty in faculties2 %} and remove faculties from your context, cuz you are repeating yourself as faculties2 and faculties hold the same queryset .
paginator = Paginator(course_list, 1)
paginator = Paginator(faculty_list, 1)
Changing your second instance name to paginator_two would solve your problem

Django disable a link if list returns empty

I don't want to display a link if the list returns empty.
template.html
{% for item in cart %}
<h1>{{ item.product.product_title }}</h1>
Remove item
{% empty %}
<p>No items in cart</p>
{% endfor %}
{% if item is not None %}
<p>
Checkout
</p>
{% endif %}
views.py
def cartview(request):
if request.user.is_authenticated():
cart = Cart.objects.filter(user=request.user.id, active=True)
orders = ProductOrder.objects.filter(cart=cart)
#total = 0
count = 0
for order in orders:)
count += order.quantity
context = {
'cart': orders,
'count': count,
}
return render(request, 'store/cart.html', context)
else:
return redirect('index:index')
I want to hide checkout link if the cart list is empty. putting it in the for loop would make the link appear many times. I want to display checkout button only once.
Instead of 'item' check for 'cart' in the template.
{% if cart %}
<p>
Checkout
</p>
{% endif %}

django blog archive, index and pagination comprehensive application

Background:
I am building a blog about my research group. On the publication archive page I am going to display all the publications of my mentor. Here there is a side column to show the archive index allowing users to view the publications by year. And at the bottom of the page there is a django paginator which separate the publications in to several pages with 7 publications per page.
Problem:
When the pagination is used, the publications is divided into a list, so the {{publication.published_time}} only contain the data in the current page rather than the whole dataset. Thus, I wrote the hard code of year information in the front end and add the url to the corresponding year.
Apparently, I wish I can get the distinct year information about all publications on the basis of the existence of a paginator. Besides, transfer the year value directly in the URL.
Code:
url.py:
url(r'^publications/(?P<year>[0-9]{4})/$', PublicationYearArchiveView.as_view(),
name="publication_year_archive"),
views.py:
class PublicationYearArchiveView(YearArchiveView):
queryset = Publication.objects.all()
date_field = "published_time"
make_object_list = True
allow_future = True
def listing(request):
limit = 7
publication_list = Publication.objects.all().order_by('published_time').reverse()
paginator = Paginator(publication_list, limit) # Show 7 publications per page
page = request.GET.get('page')
try:
publications = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer, deliver first page.
publications = paginator.page(1)
except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results.
publications = paginator.page(paginator.num_pages)
return render(request,
'research_spacecoupe/research_accomplishment.html',
{'publications': publications})
research.html:
Paginator:
{% if publications.has_other_pages %}
<ul class="pagination">
{% if publications.has_previous %}
<li>«</li>
{% else %}
<li class="disabled"><span>«</span></li>
{% endif %}
{% for i in publications.paginator.page_range %}
{% if publications.number == i %}
<li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
{% else %}
<li>{{ i }}</li>
{% endif %}
{% endfor %}
{% if publications.has_next %}
<li>»</li>
{% else %}
<li class="disabled"><span>»</span></li>
{% endif %}
</ul>
{% endif %}
Index:
<div class="sidebar-module">
<h4>Archive</h4>
<ol class="list-unstyled">
<li>all publications</li>
<li>2017</li>
<li>2016</li>
<li>2015</li>
<li>2013</li>
<li>2012</li>
<li>2011</li>
<li>2010</li>
</ol>
</div>
Note:
Now the page does work, and I can click the year(eg. 2017) to view the publications published in 2017 and click the "All publications" to view all publications. But I want to replace the number of year with distinct publications.published_time of all publications. Anything I can do to fix it?
views.py:
from django.db.models.functions import ExtractYear
from django.db.models import Count
# ...
def listing(request):
# ...
years = Publication.objects \
.annotate(year=ExtractYear('published_time')) \
.values_list('year') \
.annotate(count=Count('id')) \
.values_list('year', flat=True) \
.order_by('year')
return render(request,
'research_spacecoupe/research_accomplishment.html',
{'publications': publications,
'years': years})
research_accomplishment.html:
<div class="sidebar-module">
<h4>Archive</h4>
<ol class="list-unstyled">
<li>all publications</li>
{% for year in years %}
<li>{{ year }}</li>
{% endfor %}
</ol>
</div>

python pagination and search query on html

I am new to django.
I have a django template that renders mongodb values and accordingly paints the html. I am using pagination and search to display records.
Problem: How should I query search input in my html to display all the records which is currently masked with pagination in django.
This is how it looks with pagination.
And this is how I want to display with pagination
This is my code:
def index(request):
values = data.find()
paginator = Paginator(values, 12)
page = request.GET.get('page')
try:
listItem = paginator.page(page)
except PageNotAnInteger:
listItem = paginator.page(1)
except EmptyPage:
listItem = paginator.page(paginator.num_pages)
return render(request, 'product.html', {"values":values, "listItem":listItem})
This is my html
{% block content %}
<ul class="row catalog-list">
{% for value in values %}
<li class="col-xs-12 col-sm-6 col-md-4 col-lg-4">
<div>
<img src={{value.image_url_medium}}>
</div>
<div>
<h4 class="ellipsis-text catalog-item-name" tooltip={{value.name}}>{{value.name}}</h4>
<h5>Product Id: {{value.id_product}}</h5>
<h5>Category: {{value.catagory}}</h5>
<h5>Best Price: {{value.best_price}}</h5>
<h5>Best Price Vendor: {{value.best_price_vendor}}</h5>
<h5 class="ellipsis-text">Link:
<a href={{value.best_price_vendor_url}}>{{value.best_price_vendor_url}}</a>
</h5>
</div>
</li>
{% endfor %}
</ul>
<ul class="pagination">
<li class="step-links">
{% if listItem.has_previous %}
Previous
{% endif %}
<span class="current">
Page {{ listItem.number }} of {{ listItem.paginator.num_pages }}.
</span>
{% if listItem.has_next %}
Next
{% endif %}
</li>
</ul>
{% endblock %}
and jQuery:
$itemList = $('.catalog-list li');
console.log($itemList.length); //Prints 12
$("#filter").keyup(function(){
var filter = $(this).val();
if(filter==null){
$itemList.hide();
return;
}
var regex = new RegExp(filter, "i");
$itemList.each(function(){
if ($(this).find('h4').text().search(regex) < 0 && $(this).find('h5').text().search(regex) < 0) {
$(this).hide();
} else {
$(this).show();
}
});
});
I was new to django that time.
Its actually pretty simple here.
views.py
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from pymongo import MongoClient
register = template.Library()
port = 27017
client = MongoClient(port=port)
def people(request):
values = client.sdkUserIdDB.userIdColl.find() #getting all values from a database.
paginator = Paginator(values, 12) #putting all the values as a 12 slice so each page as 12 items from database.
page = request.GET.get('page')
try:
listItem = paginator.page(page)
except PageNotAnInteger:
listItem = paginator.page(1)
except EmptyPage:
listItem = paginator.page(paginator.num_pages)
return render(request, 'page.html', {"listItem":listItem})
templates > page.html
<ul class="pagination">
<li class="step-links">
{% if listItem.has_previous %}
Previous
{% endif %}
<span class="current">Page {{ listItem.number }} of {{ listItem.paginator.num_pages }}.</span>
{% if listItem.has_next %}
Next
{% endif %}
</li>
</ul>

django sort dict after query

have a table with websites and a many to one table with descriptions
trying to get a list, firstly getting the latest descriptions and then displaying them ordered by the content of the descriptions...
have the following in views.py
def category(request, category_name_slug):
"""Category Page"""
context_dict = {}
try:
category = Category.objects.get(slug=category_name_slug)
subcategory = SubCategory.objects.filter(category=category)
websites = Website.objects.filter(sub_categories=subcategory, online=True, banned=False)
sites = websites
descriptions = WebsiteDescription.objects.prefetch_related("about")
descriptions = descriptions.filter(about__in=sites)
descriptions = descriptions.order_by('about', '-updated')
descs = []
last_site = "" # The latest site selected
# Select the first (the latest) from each site group
for desc in descriptions:
if last_site != desc.about.id:
last_site = desc.about.id
desc.url = desc.about.url
desc.hs_id = desc.about.id
desc.banned = desc.about.banned
desc.referral = desc.about.referral
descs.append(desc)
context_dict['descs'] = descs
context_dict['websites'] = websites
context_dict['subcategory'] = subcategory
context_dict['category'] = category
except SubCategory.DoesNotExist:
pass
return render(request, 'category.html', context_dict)
this gives me a list with sites and their latest descriptions, so i have the following in category.html
{% if category %}
<h1>{{ category.name }}</h1>
{% for subcategory in category.subcategory_set.all %}
{{ subcategory.name }} ({{ subcategory.website_set.all|length }})
{% endfor %}
{% if descs %}
{% load endless %}
{% paginate descs %}
{% for desc in descs|dictsortreversed:"description"|dictsortreversed:"officialInfo" %}
<ul id='list' class='linksteps'>
<a href="/{{ desc.about_id }}" rel="nofollow" target="_blank">
<img src="/static/screenshots/{{ desc.about_id }}.png" />
</a>
<li><h3>{{ desc.about_id }}{% if desc.title %} - {{ desc.title }} {% endif %}</h3>
{% if desc.description %}<b>Description: </b>{{ desc.description }}
<br />{% endif %} {% if desc.subject %}<b>Keywords: </b>{{ desc.subject }}
<br />{% endif %} {% if desc.type %}<b>Type: </b>{{ desc.type }}
<br />{% endif %} {% if desc.officialInfo %} {% if desc.language %}<b>Language: </b>{{ desc.language }}
<br />{% endif %} {% if desc.contactInformation %}<b>Contact info: </b>{{ desc.contactInformation }}
<br />{% endif %}
{% else %}
{% endif %}
</li>
</ul>
</div>
{% endfor %}
{% show_pages %}
{% else %}
<strong>No websites currently in category.</strong>
{% endif %}
{% else %}
The specified subcategory {{ category_name }} does not exist!
{% endif %}
Initially i used dictsort
{% for desc in descs|dictsortreversed:"description"|dictsortreversed:"officialInfo"|dictsortreversed:"referral" %}
to give me the list in the desired order, so i was all happy ;)
Then however i decided i needed some pagination because the lists became too long.
django-endless-pagination works fine and does what its supposed too, however it splits up my list before the dictsort kicks in.
is there a way to sort before pagination happens and after i ordered_by at the initial query to have the latest descriptions selected?
much obliged
EDIT:
not getting any answers so my question might not be clear.
as far as i understand i need to sort the values in context_dict at the end in views.py replacing the dictsort as in the template
SOLVED:::
doing this did the trick for me to replace the dictsort.
descs1 = sorted(descs, key=operator.attrgetter('referral', 'officialInfo', 'description'), reverse=True)
context_dict['descs'] = descs1
SOLVED:::
doing this did the trick for me to replace the dictsort.
descs1 = sorted(descs, key=operator.attrgetter('referral', 'officialInfo', 'description'), reverse=True)
context_dict['descs'] = descs1

Categories

Resources