Django Conflict between 2 pagination - django

I'm trying to display all the data assoicated to every person and every house on an single template each with pagination.
The problem is everytime I view the entries of a particular data using pagination example person. The other pagination called house get reseted.
For example if I am on page 3 for house and I try to view other entries for page person . The house pagination will get reset back to 1. How do I fix this pagination conflict?
models
class Person(models.Model):
user = models.ForeignKey(User)
name = models.CharField(max_length=100, blank=True)
def __unicode__(self):
return self.name
class House(models.Model):
user = models.ForeignKey(User)
name = models.CharField(max_length=100)
views
def Display(request):
user= User.objects.get(username=request.user)
comment = Person.objects.get(user=user)
posts = House.objects.filter(user=user)
paginator = Paginator(comment, 5)
try: n = int(request.GET.get("n", '1'))
except ValueError: page = 1
try:
comment = paginator.page(n)
except (InvalidPage, EmptyPage):
comment = paginator.page(paginator.num_pages)
paginator = Paginator(posts, 5)
try: page = int(request.GET.get("page", '1'))
except ValueError: page = 1
try:
posts = paginator.page(page)
except (InvalidPage, EmptyPage):
posts = paginator.page(paginator.num_pages)
return render(request,'display.html',{'posts':posts,'comment':comment})
HTML
{% for p in posts.object_list %}
{{p.name}}
{% endfor %}
{% if posts.object_list and posts.paginator.num_pages > 1 %}
<div class="pagination" style="margin-top: 20px; margin-left: -20px; ">
Page {{ posts.number }} of {{ posts.paginator.num_pages }}<br>
{% if posts.has_previous %}
<a class="Link" href= "{% if formula %}?text={{formula}}&{% else %}?{% endif %}page={{ posts.previous_page_number }}">newer entries << </a>
{% endif %}
{% if posts.has_next %}
<a class="Link" href="{% if formula %}?text={{formula}}&{% else %}?{% endif %}page={{ posts.next_page_number }}"> >> older entries</a>
{% endif %}
</span>
</div>
{% endif %}
{% for c in comment.object_list %}
{{c.name}}
{% endfor %}
{% if comment.object_list and comment.paginator.num_pages > 1 %}
Page {{ comment.number }} of {{ comment.paginator.num_pages }}
{% if comment.has_previous %}
<a class="Link" href= "?n={{ comment.previous_page_number }}">newer entries << </a>
{% endif %}<br>
{% if comment.has_next %}
<a class="Link" href="?n={{ comment.next_page_number }}"> >> older entries</a>
{% endif %}
</span>
</div>
{% endif %

First off, your variable names versus how you describe everything is quite confusing.
The issue is you are using two different variables for the page: n for person (or comment) and page for house (or posts). In each of your <a href=""> you need to set both n and page not just one. So:
<a class="Link" href= "{% if formula %}?text={{formula}}&{% else %}?{% endif %}page={{ posts.previous_page_number }}&n={{ comment.number }}">newer entries << </a>
<a class="Link" href="{% if formula %}?text={{formula}}&{% else %}?{% endif %}page={{ posts.next_page_number }}&n={{ comment.number }}"> >> older entries</a>
<a class="Link" href= "?n={{ comment.previous_page_number }}&page={{ posts.number }}">newer entries << </a>
<a class="Link" href="?n={{ comment.next_page_number }}&page={{ posts.number }}"> >> older entries</a>

In the same view you change the value of paginator two times
paginator = Paginator(comment, 5)
# here you have code that does stuff and some lines below
paginator = Paginator(posts, 5)
if you want two paginators in the same view you should also name them differently (and add them to your context variables)
Something I can suggest is to have an ajax pagination view that you're going to call to switch between pages in your templates. In this way, you can change page to each resultset separately without needing to reload the entire view (and probably loosing your pagination state)

Related

For loop inside a IF condition to show right category on django template

I'm trying to show the correct articles in the category section using an if condition with a for loop inside, so far I'm displaying all the articles and not the only ones that supposed to be in the category.
home.html screeenshot
home.html
{% if articles.category == Sports %}
{% for article in articles %}
<div class="position-relative">
<img class="img-fluid w-100" src="{{article.cover.url}}" style="object-fit: cover;">
<div class="overlay position-relative bg-light">
<div class="mb-2" style="font-size: 13px;">
{{article.title}}
<span class="px-1">/</span>
<span>{{article.created_at}}</span>
</div>
<a class="h4 m-0" href="">{{article.description}}</a>
</div>
</div>
{% endfor %}
{% endif %}
views.py
def home (request):
cats = Category.objects.all()
articles = Article.objects.filter( is_published=True).order_by('-category')
return render (request,'pages/home.html',
context={
'cats': cats,
'articles': articles
})
Instead of hardcoding it like that, you could let the users search for categories with something like this:
articles = Article.objects.filter(category__icontains=q).values('title')
where q would be the user input in the form.

Paginator not working properly while filtering the querysets?

Here filtering working fine and also paginator works fine on the first page. The issue is while going on the next page if it has any.It shows the remaining data on the next page but if I go on the next page then It displays 0 data.
Paginator doesnot working in the filter view only. So I think the issue is in this view only since I have the same template for search and list queryset view and in there the pagination works fine.
EDIT: I am using the same template with same context name for search, filter and list view but only in filter the pagination issue came.
search url looks like this
(at first) search/?q= and in the next page search/?page=2 while going previous page search/?page=1 # this works fine
While doing filter I expect the same but it is not working. In the filter/?page=2 there is no data.
views
def get(self, request):
results = MyModel.objects.none()
parameter = request.GET.get('param', '')
today = datetime.datetime.today()
current_month = today.month
past_7_days = today - datetime.timedelta(days=7)
if parameter == '0':
return redirect('show_all_querysets')
elif parameter == '1':
results = MyModel.objects.filter(datetime__date=today.date()).order_by('-datetime')
elif parameter == '2':
results = MyModel.objects.filter(datetime__range=[past_7_days, today]).order_by('-datetime')
elif parameter == '3':
results = MyModel.objects.filter(datetime__month=current_month).order_by('-datetime')
querysets = Paginator(results, 10).get_page(request.GET.get('page'))
return render(request, 'show_all_querysets.html', {'querysets': querysets})
Search View
def get(self, request):
q = request.GET.get('q', '')
results = MyModel.objects.filter(message__icontains=q)).order_by('-datetime')
querysets = Paginator(results, 10).get_page(request.GET.get('page'))
return render(request, 'show_all_querysets.html', {'querysets': querysets})
template
<div class="paginate-navigate ml-3">
{% if querysets.has_previous %}
<a href="?{% if prev_url %}{{ prev_url }}{% endif %}page={{ querysets.previous_page_number}}">
<i title="previous" class="ic-chevron-left left"></i>
</a>
{% else %}
<a disabled href="#">
<i class="ic-chevron-left left"></i>
</a>
{% endif %}
{% if querysets.has_next %}
<a href="?{% if prev_url %}{{ prev_url }}{% endif %}page={{ querysets.next_page_number}}">
<i title="next" class="ic-chevron-right right ml-2"></i>
</a>
{% else %}
<a href="#">
<i class="ic-chevron-right right ml-2"></i>
</a>
{% endif %}
</div>
If you have both search fileter and pagination in query parameters then your url goes like your_url/?params=some&page=2
to achieve this first pass your params in context
return render(request, 'show_all_querysets.html', {'querysets': querysets,'parameter':parameter})
and then suppose you have previous and next buttons, so give href like this:
{% if querysets.has_previous %}
<a class="btn btn-outline-dark" href="{% if parameter %}{{ request.get_full_path }}&page={{ querysets.previous_page_number }}{% else %}?page={{ querysets.previous_page_number }}{% endif %}">Previous</a>
{% else %}
<button type="button" disabled class="btn btn-outline-dark" title = "No querysets available">Previous</button>
{% endif %}
{% if querysets.has_next %}
<a class="btn btn-outline-dark" href="{% if parameter %}{{ request.get_full_path }}&page={{ querysets.next_page_number }}{% else %}?page={{ querysets.next_page_number }}{% endif %}">Next</a>
{% else %}
<button disabled type="button" class="btn btn-outline-dark" title = "No querysets available">Next</button>
{% endif %}
querysets = Paginator(results, 10).page(request.GET.get('page'))

I don't know why my page isn't paginating i don't get any errors pls help :)

The page is supposed to get paginated but it doesn't I don't know what I did wrong. If anyone can help me figure it out i will appreciate
This is for a comment section on a site and I don't really know how to fix it. I've been looking the problem up on the web with no results then came here
from django.core.paginator import Paginator
def Home_view(request):
posts = Post.objects.order_by("-date_posted")
all_experiences = Experience.objects.order_by("-id")
all_educations = Education.objects.order_by("-id")
all_skills = Skill.objects.all()
paginator = Paginator(posts, 1)
page = request.GET.get('page')
post_list = paginator.get_page(page)
context = {
'posts': posts,
'all_experiences': all_experiences,
'all_educations': all_educations,
'all_skills': all_skills,
}
return render(request, 'resume.html', context)
Html Page supposed to get paginated
{% if is_paginated %}
<div class="pagination">
<span class="step-links">
{% if post_list.has_previous %}
« first
<a href="?page={{ post_list.previous_page_number }}">previous
</a>
{% endif %}
<span class="current">
Page{{post_list.number}}of{{post_list.paginator.num_pages}}.
</span>
{% if post_list.has_next %}
next
<a href="?page={{ post_list.paginator.num_pages }}">last»
</a>
{% endif %}
</span>
</div>
{% endif %}
{% else %}
the page is supposed to show 5 posts at once but doesn't and doesn't throw out any errors it just doesn't work
It looks like you aren't adding post_list to your context so {% if post_list.has_previous %} does nothing. You are passing posts which is the unpaginated list of posts. You will also need to add is_paginated to the context. Try updating context to something like:
context = {
'all_experiences': all_experiences,
'all_educations': all_educations,
'all_skills': all_skills,
'post_list': post_list,
'is_paginated': True,
}

Django pagination - 5k objects

As a continuation of this question Django pagination with bootstrap any my works under my Contacts app I have to ask for your help once more. I have a problem I cannot resolve. I used few suggestions about pagination but all that is changing is the bottom pagination menu. My app is still loading all 5k objects every time, over and over. I am new at this, this app is my first project and this is the final 'big' missing part. I promiss to post final cone when I'm done :)
Best regards.
views.py
def index(request):
contacts_list = contacts.objects.all()
contacts_filter = LFilter(request.GET, queryset=contacts_list)
paginator = Paginator(contacts_list, 50)
try:
page = int(request.GET.get('page','1'))
except:
page = 1
try:
contacts = paginator.page(page)
except PageNotAnInteger:
contacts = paginator.page(1)
except EmptyPage:
contacts = paginator.page(paginator.num_pages)
index = contacts.number - 1
max_index = len(paginator.page_range)
start_index = index - 3 if index >= 3 else 0
end_index = index + 3 if index <= max_index - 3 else max_index
page_range = paginator.page_range[start_index:end_index]
return render(
request, 'index.html',
context={'filter': contacts_filter,
'contacts': contacts,
'page_range': page_range, }
)`
index.py
{% for obj in filter.qs %}
Code for contact information to display
{% endfor %}
<div class="prev_next">
{% if contacts.has_previous %}
<a class="prev btn btn-info" href="?page={{contacts.previous_page_number}}">Prev</a>
{% endif %}
{% if contacts.has_next %}
<a class="next btn btn-info" href="?page={{contacts.next_page_number}}">Next</a>
{% endif %}
<div class="pages">
<ul>
{% for pg in page_range %}
{% if contacts.number == pg %}
<li>{{pg}}</li>
{% else %}
<li>{{pg}}</li>
{% endif %}
{% endfor %}
</ul>
</div>
<span class="clear_both"></span>
</div>

What's the Django way of doing an "order by" dropdown filter?

I need a basic search query 'order by' dropdown to use with a RawQuerySet. I did some searching and couldn't find a specific example although the existence of Forms and Widgets which i don't fully understand makes me think I’m reinventing the wheel.
view
def search(request, limit=1000):
query = request.GET.get('q')
mapping = OrderedDict([
('time_desc', 'time_modified DESC'),
('time_asc', 'time_modified ASC'),
('relevance', None)])
sort = request.GET.get('sort')
_ = mapping.get(sort)
order_by = 'ORDER BY %s' % _ if _ else ''
dropdown = {'choices': mapping.keys(),
'selected_choice': sort if sort else 'relevance'}
query = sanitize_query(query)
results = SphinxTable.objects.db_manager('sphinx').raw("SELECT * FROM products WHERE MATCH('%(query)s') %(order_by)s LIMIT %(limit)s" % locals())
return render(request,
'search.html',
{'results': results,
'dropdown': dropdown})
template
<ul id="filter">
<li>
<h3>{{ dropdown.selected_choice }}▾</h3>
<ul>
{% for choice in dropdown.choices %}
{% if choice == dropdown.selected_choice %}
<li># {{ choice|capfirst }}</li>
{% else %}
<li>
<a href="{{ request.path }}?q={{ request.GET.q }}&sort={{ choice }}">
{{ choice|capfirst }}
</a>
</li>
{% endif %}
{% endfor %}
</ul>
</li>
</ul>