I'm building a simple blog app using Django.
This app has a main template blog.html which is shared between the following views:
blog (url: /blog/[page number])
Main page of the blog, displays the last articles
search (url: /search/<query>/[page number])
Will display the articles who match the query
category (url: /category/<category name>/[page number])
Will display the articles from the given category
Each a this views provides the template blog.html with an object page obtained using the function Paginator each time with a different objects list (depending on the view).
Here is my problem:
The template blog.html contains a pager
<ul class="pager">
{% if page.has_previous %}
<li class="previous">
<a href="{{ url_previous_page }}" class="btn btn-primary" >← Older</a>
</li>
{% endif %}
{% if page.has_next %}
<li class="next">
<a href="{{ url_next_page }}" class="btn btn-primary" >Newer →</a>
</li>
{% endif %}
</ul>
How can I define in an elegant way the values of url_next_page and url_previous_page in all the views?
You shouldn't really need to supply the links for the next and previous buttons like that. I would suggest changing your pagination code to be something like this:
<div class="pagination-wrap">
<span class="pagination-links">
{% if page_obj.has_previous %}
{% endif %}
<span class="current">
{{ page_obj.number }} of {{ page_obj.paginator.num_pages }}
</span>
{% if page_obj.has_next %}
{% endif %}
</span>
<div>{{ page_obj.start_index }} to {{ page_obj.end_index }} of {{ page_obj.paginator.count }}</div>
</div>
In your views, all you need to specify is the number of objects to paginate by with paginate_by = 15.
If you really want to, you could create a mixin for your list views to use which has a method that could return the url you want.
Related
The reason I ask is that I'm parsing a large List into a Django template, we're talking about 100,000 items being rendered into a table and it's painfully slow at loading!
or is there a method that I've completely missed?
I'm currently using {% regroup %} to group headers together.
with the Paginator class
from django.views.generic import ListView
from myapp.models import Contact
class ContactList(ListView):
paginate_by = 2
model = Contact
and the template
{% for contact in page_obj %}
{# Each "contact" is a Contact model object. #}
{{ contact.full_name|upper }}<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>
https://docs.djangoproject.com/en/3.1/topics/pagination/
I want to add simple back/next pagination in my item detail view.
How can I do that ?
I have something like that in my template:
{% if is_paginated %}
<div class="pagination">
<span class="page-links">
{% if page_obj.has_previous %}
Back
{% endif %}
{% if page_obj.has_next %}
Next: {{ item.title }}
{% endif %}
</span>
</div>
{% endif %}
The main thing is that I want to do this in ItemDetailView, not in ItemListView, because in list view I have all items, and I just want to go between items in detail view.
Thanks a lot for help.
I have a custom context processor which I use to generate a dynamic menu and a list of current apps, site-wide:
from portal.models import *
def base_items(request):
return {
...
'app_items': App.objects.filter(isonline=True),
'menu_items': MainMenu.objects.all().order_by('position'),
}
EDIT:
My template (note that many of these urls are outside of the Django framework and vary depending on language. Hence the need to hardcode them into the db fields:
<ul class="menu">
{% for item in menu_items %}
{% if LANGUAGE_CODE = "en-us" %}
<li><a title="{{ item.title_en }}" href="{{ item.url_en }}">{{ item.title_en }}</a>
<ul>
{% for subitem in item.submenu_set.all %}
<li><a title="{{ subitem.title_en }}" href="{{ subitem.url_en }}">{{ subitem.title_en }}</a></li>
{% endfor %}
</ul>
</li>
{% else %}
<li><a title="{{ item.title_es }}" href="{{ item.url_es }}">{{ item.title_es }}</a>
<ul>
{% for subitem in item.submenu_set.all %}
<li><a title="{{ subitem.title_es }}" href="{{ subitem.url_es }}">{{ subitem.title_es }}</a></li>
{% endfor %}
</ul>
</li>
{% endif %}
{% endfor %}
</ul>
My question is - how can I cache these results, which don't change very frequently?
I have tried the #cache_page decorator but I can see my pages still accessing the db for the menu items objects.
Any help much appreciated.
You can use django low level cache API. Note that you might have to cast the querysets to list.
Or, you could cache the template fragment that uses these querysets, because querysets are lazy.
Try to return lamdas expressions to your templates:
'app_items': lambda: App.objects.filter(isonline=True),
that way it does not get compiled/cached and works dynamically.
Hey I have been plugging away trying to get haystack working with whoosh to implement a search backend for a django cms project i have been working on. After figuring out some really weird permissions errors i can almost taste sucess.
I now have haystack creating the indexes correctly and it will even display results for a custom app i have created an index for however i cannot get it to display any results for the cms page stuff. There are results being returned as im not getting the "No Results" message but nothing is being printed out in the results.html template.
bearing in mind that im letting django-cms-search handle the indexing for the cms app i didnt think i would need to add anything extra to get the results to display.
So to outline what i have so far
Haystack installed with a Whoosh backend
my setting.py setting are
HAYSTACK_SITECONF = 'lactoseintolerant.lactose_search.search_sites'
HAYSTACK_SEARCH_ENGINE = 'whoosh'
HAYSTACK_WHOOSH_PATH = '/home/mike/sites/lactosetoloerant/lactoseintolerant/whoosh'
HAYSTACK_SEARCH_RESULTS_PER_PAGE = 50
my search_sites.ph file looks like
import haystack
from cms.models import monkeypatch_reverse
from cms.plugin_pool import plugin_pool
monkeypatch_reverse()
haystack.autodiscover()
i have a custom index for my Topics Model that looks like so (This is working and resturning Reuslts)
from topics.models import Topic
from haystack.indexes import *
from haystack import site
class TopicIndex(SearchIndex):
text = CharField(document=True, use_template=True)
def index_queryset(self):
"""
This is used when the entire index for model is updated, and should only include
public entries
"""
return Topic.objects.filter(active=True)
site.register(Topic, TopicIndex)
My results.html template look like
{% extends "base.html" %}
{% load cache cms_tags menu_tags %}
{% block base_content %}
<div id="panel-left">
{% block nav %}
<ul id="nav-left">
{% show_menu 1 100 100 100 %}
</ul> <!-- #nav-left -->
{% endblock %}
{% block panel_left %}
{% endblock %}
</div>
{% block panel_right %}
<div id="panel-main">
{% ifequal q '' %}
<h1 id="page-head-2">Search Results Page</h1>
<p>Please provide search criteria or keywords</p>
<br />
<form action=".">
<p>
<input type="text" name="q" value="{{ q }}">
<input type="submit" name="search" value="Search">
</p>
</form>
{% else %}
<h1 id="page-head-2">Search Results - page {{ request.GET.page|default:1 }} of {{ paginator.num_pages }}</h1>
<h1 id="page-head-2">Found {{ paginator.count }} for <span id="searchString">'{{ q }}'</span></h1>
<form action=".">
<p>
<input type="text" name="q" value="{{ q }}">
<input type="submit" name="search" value="Search">
</p>
</form>
<ul id="searchResults">
{% for item in current_page.object_list %}
<li class="searchResult">
<h2 class="searchTitle">{{ forloop.counter }}. {{ item.get_title }}</h2>
<a class="searchLink" href="{{ item.get_absolute_url }}">{{ item.get_absolute_url }}</a>
</li> <!-- .searchResult -->
{% endfor %}
</ul>
{% if paginator.num_pages > 1 %}
<div id="pagination">
{% for page_range_item in paginator.page_range %}
{% if not request.GET.page and page_range_item == 1 or request.GET.page == page_range_item|safe %}
<span class="pag-link current" href="/topics/?page={{ page_range_item }}">{{ page_range_item }}</span>
{% else %}
<a class="pag-link" href="/search/?q={{ q }}&page={{ page_range_item }}">{{ page_range_item }}</a>
{% endif %}
{% endfor %}
</div>
{% endif %}
{% endifequal %}
</div>
{% endblock %}
{% endblock %}
Im clearly missing something obvious here any help would be grealt appreciated!!
Cheers
i think you got it almost, try to change {{ item.get_absolute_url }} to {{ item.object.get_absolute_url }} inn your results.html file.
I am using Django pagination - and it works great ;) ...
But in some cases I have a URL with queryies - and when i use the default template setup for pagination - it wont work..
<div class="pagination">
<span class="step-links">
{% if contacts.has_previous %}
previous
{% endif %}
<span class="current">
Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}.
</span>
{% if contacts.has_next %}
next
{% endif %}
</span>
</div>
How can I do it ? ..
My url can look like this:
http://www.example.com/tag/?tag=fewa&met=23&g=2&page=2
or
http://www.example.com/tag/?tag=fewa&g=2&t=ewq&page=2
What can I do at the pre and next position?
forrige
I got IT ;)