I'm using the standard django paginator in my generic view like this:
def get_context_data(self, **kwargs):
context = super(ArchivePagedView, self).get_context_data(**kwargs)
article_list = Article.published
#=====================================
paginator = Paginator(article_list, self.paginate_by)
page = self.request.GET.get('page')
try:
article_list = paginator.page(page)
except PageNotAnInteger:
article_list = paginator.page(1)
except EmptyPage:
article_list = paginator.page(paginator.num_pages)
if 'reverse' in self.request.GET:
article_list = article_list.reverse() #This doesn't work!
else:
article_list = article_list.all()
context['article_list'] = article_list
return context
As you can see I want to override article_list with the same list, but in reversed direction, if reverse is in the URL in behind the question mark. That information I get by 'reverse' in self.request.GET.
But I get an error: AttributeError: 'Page' object has no attribute 'reverse'. How do I reverse this? (I don't want to have duplicated code in my template.)
Before I fixed this by making an extra context variable (context['reverse']) which says whether the list should be reversed or not, and then I used duplicated code like this:
{% if reverse %}
{% for article in article_list reversed %}
... some code
{% endfor %}
{% else %}
{% for article in article_list %}
... the same code
{% endfor %}
{% endif %}
I wonder if there was no better solution.
Try this
article_list.object_list = list(reversed(article_list.object_list))
Related
I'm trying to implement pagination on my Django app that is based on the filtered queries, but the pagination shows all the objects even the ones not filtered, any insight on what I'm doing wrong?
Any assistance would be appreciated.
def searchPropertyListView(request):
city = City.objects.all().annotate(
num_property=Count("property")).order_by("-num_property")
categories = Category.objects.all()
purposes = Purpose.objects.all()
featured = list(Property.objects.filter(featured=True))
shuffle(featured)
querySet = Property.objects.all()
city_or_neighborhood = request.GET.get('city_or_neighborhood')
category = request.GET.get('category')
purpose = request.GET.get('purpose')
if city_or_neighborhood != '' and city_or_neighborhood is not None:
querySet = querySet.filter(Q(city__title__icontains=city_or_neighborhood)
| Q(neighborhood__title__icontains=city_or_neighborhood)
).distinct()
if category != '' and category is not None:
querySet = querySet.filter(category__title=category)
if purpose != '' and purpose is not None:
querySet = querySet.filter(purpose__title=purpose)
paginator = Paginator(querySet, 1)
page = request.GET.get('page')
try:
querySet = paginator.page(page)
except PageNotAnInteger:
querySet = paginator.page(1)
except EmptyPage:
querySet = paginator.page(paginator.num_pages)
Paginator.get_page is New since Django 2.0.
def searchPropertyListView(request):
...
Your code here
...
paginator = Paginator(querySet, 1)
page = request.GET.get('page')
page_obj = paginator.get_page(page)
And html
{% for property in page_obj %}
{{ property.city.title }}<br>
...
{% endfor %}
<div class="pagination">
<span class="step-links">
{% if page_obj.has_previous %}
« first
previous
{% endif %}
<span class="current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
next
last »
{% endif %}
</span>
</div>
See Using Paginator in a view function
I want to sort my table columns both ways (ascending and descending, switch upon pressing a button). The problem I have is my tables go out of order when I switch a page.
views.py
def company_index(request):
order_by = request.GET.get('order_by')
companies = Company.objects.all().order_by(Lower(order_by))
paginator = Paginator(companies, 10)
page = request.GET.get('page')
try:
all_companies = paginator.page(page)
except PageNotAnInteger:
all_companies = paginator.page(1)
except EmptyPage:
all_companies = paginator.page(paginator.num_pages)
return render(request, 'companies/company_index.html',
{'all_companies': all_companies})
Here is how I display data in my templates (I shortened class names for better post visibility):
<thead>
<tr>
<th>Company name <a class="glyphicon" href="?order_by=company_name"></a></th>
<th>Company address <a class="glyphicon" href="?order_by=company_address"></a></th>
<th>Tax ID <a class="glyphicon" href="?order_by=tax_id"></a></th>
<th>Company ID <a class="glyphicon" href="?order_by=company_id"></a></th>
<th>KRS Number <a class="glyphicon" href="?order_by=KRS_number"></a></th>
</tr>
</thead>
My pagination code:
<ul class="pagination">
{% if all_companies.has_previous %}
<li>previous</li>
{% endif %}
<li class="disabled"><a>Page {{ all_companies.number }} of {{ all_companies.paginator.num_pages }}</a></li>
{% if all_companies.has_next %}
<li>next</li>
{% endif %}
</ul>
When I switch to other page {{order_by}} passes None. Also, how can I make it sort descending or ascending, after pressing a button?
I want to do it without outside apps or libraries, to have a better understanding of django.
You forgot to add order_by in the context:
return render(request, 'companies/company_index.html',
{'all_companies': all_companies, 'order_by': order_by})
Ascending/descending in template:
company name ascending
company name descending
...
previous
...
next
In the view:
def company_index(request):
order_by = request.GET.get('order_by')
direction = request.GET.get('direction')
ordering = Lower(order_by)
if direction == 'desc':
ordering = '-{}'.format(ordering)
companies = Company.objects.all().order_by(ordering)
paginator = Paginator(companies, 10)
page = request.GET.get('page')
try:
all_companies = paginator.page(page)
except PageNotAnInteger:
all_companies = paginator.page(1)
except EmptyPage:
all_companies = paginator.page(paginator.num_pages)
return render(request, 'companies/company_index.html',
{'all_companies': all_companies,
'order_by': order_by, 'direction': direction})
I am facing a slight problem in django pagination using generic views, passing multiple models to a template with one of the models that has to paginated. The pager does not show next pages on my template,but produces just a single page.
Below is my code :
views.py:
class homeView(generic.ListView):
template_name = 'success/home_page.html'
context_object_name="articles"
paginate_by = 3
def get_queryset(self):
articles =Articles.objects.order_by('article_title')
paginator = Paginator(articles,self.paginate_by)
page = self.request.GET.get('page')
try:
articles = paginator.page(page)
except PageNotAnInteger:
articles = paginator.page(1)
except EmptyPage:
articles = paginator.page(paginator.num_pages)
return articles
def get_context_data(self,**kwargs):
context = super(homeView, self).get_context_data(**kwargs)
context['quote'] = Quotes.objects.order_by('quote')
return context
Template:
{% for article in articles %}
{{ article.article_title}}
{{ article.aticle_hit}}
{% endfor % %}
<div class="pagination">
{% if articles.has_previous %}
<a class="navlink" href="?page={{articles.previous_page_number}}">Prev</a>
{% endif %}
Page {{articles.number}} of {{articles.paginator.num_pages}}
{% if articles.has_next %}
<a class="navlink" href="?page={{articles.next_page_number}}">next</a>
{% endif %}
</div>
Just page one of my paginated page shows. Next and previous do not work at all. Please help me with a better way to do pagination using generic view and passing multiple models in to a single template.
As said, trim down. If you get an error, post it, that will help.
class homeView(generic.ListView):
template_name = 'success/home_page.html'
context_object_name = "articles"
paginate_by = 3
model = Articles
def get_context_data(self, **kwargs):
context = super(homeView, self).get_context_data(**kwargs)
context['quote'] = Quotes.objects.order_by('quote')
return context
I'm fairly new to Wagtail, and I am in the process of creating a site that will have a Resources (blog) section and I'm not sure how to implement pagination so that there are only 5 posts on each page and the user has to click a number (1, 2, 3, etc.) to go to the next page to see the next 5 posts.
I have this in my template for the pagination section of the resource/blog index page:
<ul class="pagination">
<li><i class="fa fa-angle-left"></i></li>
<li class="active">1</li>
<li>2</li>
<li>3</li>
<li><i class="fa fa-angle-right"></i></li>
</ul>
What code do I need to incorporate to make this functional? Thanks in advance.
Django provides the module django.core.paginator for this purpose: https://docs.djangoproject.com/en/1.10/topics/pagination/ . Using this within Wagtail is very similar to the examples in the Django documentation - the only real difference is that when you're setting up the Paginator object to be passed to the template, you do that with a get_context method on the page model, instead of a view function. Your model definition will look something like this:
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
class ResourceIndexPage(Page):
# ...
def get_context(self, request):
context = super(ResourceIndexPage, self).get_context(request)
# Get the full unpaginated listing of resource pages as a queryset -
# replace this with your own query as appropriate
all_resources = ResourcePage.objects.live()
paginator = Paginator(all_resources, 5) # Show 5 resources per page
page = request.GET.get('page')
try:
resources = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer, deliver first page.
resources = paginator.page(1)
except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results.
resources = paginator.page(paginator.num_pages)
# make the variable 'resources' available on the template
context['resources'] = resources
return context
Within your template, you can now loop over the items using {% for resource in resources %}, and display the pagination links as follows:
<ul class="pagination">
{% if resources.has_previous %}
<li><i class="fa fa-angle-left"></i></li>
{% endif %}
{% for page_num in resources.paginator.page_range %}
<li {% if page_num == resources.number %}class="active"{% endif %}>{{ page_num }}</li>
{% endfor %}
{% if resources.has_next %}
<li><i class="fa fa-angle-right"></i></li>
{% endif %}
</ul>
I very much appreciate that you got me here - thanks so much for the assist. I had to make some adjustments to make it work. Here's the model if anyone comes across the same issue:
class NewsIndexPage(Page):
intro = RichTextField(blank=True)
def get_context(self, request):
context = super(NewsIndexPage, self).get_context(request)
# Get the full unpaginated listing of resource pages as a queryset -
# replace this with your own query as appropriate
blogpages = self.get_children().live().order_by('-first_published_at')
paginator = Paginator(blogpages, 3) # Show 3 resources per page
page = request.GET.get('page')
try:
blogpages = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer, deliver first page.
blogpages = paginator.page(1)
except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results.
blogpages = paginator.page(paginator.num_pages)
# make the variable 'resources' available on the template
context['blogpages'] = blogpages
return context
...and here's the HTML:
<ul class="pagination">
{% if blogpages.has_previous %}
<li>
<i class="fa fa-angle-left"></i>
</li>
{% endif %}
{% for page_num in blogpages.paginator.page_range %}
<li {% if page_num == blogpages.number %} class="active"{% endif %}>
{{ page_num }}
</li>
{% endfor %}
{% if resources.has_next %}
<li>
<i class="fa fa-angle-right"></i>
</li>
{% endif %}
</ul>
It works like a charm - and adds to the learning curve!
In case it's useful to anyone, I wanted this to work as closely as possible to the class-based view ListView, and so I ended up with this:
from django.core.paginator import Paginator, InvalidPage
from django.http import Http404
from django.utils.translation import gettext as _
from wagtail.core.models import Page
class ArticleListPage(Page):
# Some Page variables set here. #
# Pagination variables:
paginator_class = Paginator
paginate_by = 10
page_kwarg = 'page'
paginate_orphans = 0
allow_empty = False
def get_context(self, request):
context = super().get_context(request)
queryset = Page.objects.live()
paginator, page, queryset, is_paginated = self.paginate_queryset(
queryset, self.paginate_by, request)
context.update({
'paginator': paginator,
'page_obj': page,
'is_paginated': is_paginated,
'object_list': queryset,
})
return context
def paginate_queryset(self, queryset, page_size, request):
"""
Adapted from the ListView class-based view.
Added the request argument.
"""
paginator = self.paginator_class(
queryset,
self.paginate_by,
orphans=self.paginate_orphans,
allow_empty_first_page=self.allow_empty)
page_kwarg = self.page_kwarg
page = request.GET.get(page_kwarg) or 1
try:
page_number = int(page)
except ValueError:
if page == 'last':
page_number = paginator.num_pages
else:
raise Http404(_("Page is not 'last', nor can it be converted to an int."))
try:
page = paginator.page(page_number)
return (paginator, page, page.object_list, page.has_other_pages())
except InvalidPage as e:
raise Http404(_('Invalid page (%(page_number)s): %(message)s') % {
'page_number': page_number,
'message': str(e)
})
This will give you the same paginator, page_obj, is_paginated and object_list variables in your template that you would get with a normal Django ListView.
(Using python 3, Django 2.1 and Wagtail 2.3.)
I'm been trying to implement django paginator into my whiteboard app so I can split the pictures into different pages.
The problem occurs when I attempt to move across different pages.I limited each page to 1 objects and uploaded few pictures to test if the pagination works between pages but when I try to move across different pages using the pagination method, it doesn't respond.
http://img854.imageshack.us/img854/3303/94627386.jpg
I'm been researching and testing for solutions to this problems through the django pagination docs and I think problem lay at the pagination module method at my template.
My views.py
def Boat(request ,animal_id):
if not request.user.is_authenticated():
return HttpResponseRedirect(reverse('world:LoginRequest'))
picture = Picture.objects.filter(board=animal_id)
paginator = Paginator(picture,1)
page = request.GET.get('page')
try:
picture = paginator.page(page)
except PageNotAnInteger:
picture = paginator.page(1)
picture = paginator.page(paginator.num_pages)
return render(request,'boat.html',{'picture':picture })
My boat.html
{% if picture.object_list %}
<ul>
{% for pet in picture.object_list %}
{% if pet.image %}
<br>
<img src= "{{ pet.image.url }}" </a>
<br>
</a>
</li>
{% endif %}
<br>
View Comment Like<br/>
{% for c in picture %}
{% ifequal c.picture.id pet.id %}
<br>{{ c.body }}</li>
<br>{{ c.created}}</li>
<br>{{ c.user}}</li>
{% endifequal %}
% endfor %}
{% endfor %}
</ul>
{% endif %}
Add Pictures to your board<br/>
{% if number %}
{{number}}
{% endif %}
Return back to Profile<br/>
<br><br><br><br><br>
<div class="pagination">
<span class="step-links">
{% if picture.has_previous %}
previous
{% endif %}
<span class="current">
Page {{ picture.number }} of {{ picture.paginator.num_pages }}.
</span>
{% if picture.has_next %}
next
{% endif %}
</span>
</div>
Parts of my module
class Picture(models.Model):
user = models.ForeignKey(User)
board = models.ForeignKey(Board,blank=False,null=False,related_name='board')
image = models.FileField(upload_to="images/",blank=True)
description = models.TextField()
is_primary = models.BooleanField(default=False)
def __unicode__(self):
return self.description
def Boat(request ,animal_id):
if not request.user.is_authenticated():
return HttpResponseRedirect(reverse('world:LoginRequest'))
picture = Picture.objects.filter(board=animal_id)
paginator = Paginator(picture,1)
try:
page = int(request.GET.get('page', '1'))
except ValueError:
page = 1
try:
picture = paginator.page(page)
except (EmptyPage, InvalidPage):
picture = paginator.page(paginator.num_pages)
picture = paginator.page(paginator.num_pages)
return render(request,'boat.html',{'picture':picture })
#this is view
#this is views files
#login_required(login_url='/login')
# class Base_page_list2(ListView):
def Base_page_list(request,*args, **kwargs):
# tiket = Tiket.objects.all()
# lastest_tiket =Tiket.objects.order_by('-id').all()[:8]
tiket_list = Tiket.objects.all()
paginator = Paginator(tiket_list,2)
page = request.GET.get('page')
page_obj = paginator.get_page(page)
context ={
'tiket':None,
'page_obj':page_obj,
}
context['tiket']=['page_obj']
if request.user.is_superuser:
context['tiket']= Tiket.objects.all()
elif not request.user.is_hrm:
raise Http404('شما نمی توانید به این صحفه دسترسی داشته باشید')
elif request.user.is_mis :
context['tiket']= Tiket.objects.filter(status_tag='s')
elif request.user.is_mali:
context['tiket']=Tiket.objects.filter(status_tag='m')
elif request.user.is_mosh:
context['tiket']=Tiket.objects.filter(status_tag='c')
elif request.user.is_modir:
context['tiket']=Tiket.objects.filter(status_tag='b')
elif request.user.is_kz:
context['tiket']=Tiket.objects.filter(status_tag='k')
elif request.user.is_pa:
context['tiket']=Tiket.objects.filter(status_tag='p')
else:
context['page_obj']['tiket']=Tiket.objects.filter(author=request.user)
return render(request,'hrm_account/base.html',context)
`enter code here`error
File "/home/ali/Desktop/testsharen2/sharen/sharen_hrm/views.py", line 128, in Base_page_list
context['page_obj']['tiket']=Tiket.objects.filter(author=request.user)
TypeError: 'Page' object does not support item assignment