Comment utiliser la pagination avec Django 1.3?
La documentation n'est pas très claire à ce sujet.
Qu'est-ce qui se passe dans mon views.py
?
Qu'est-ce qui se passe dans mon modèle?
Qu'est-ce qui va dans mon fichier URLconf?
Je pense que vous demandez des informations sur l'utilisation de la pagination avec les nouvelles vues basées sur les classes car, avec les vues traditionnelles basées sur les fonctions, il est facile à trouver. J'ai trouvé que le simple fait de définir la variable paginate_by
suffit à activer la pagination. Voir dans Vues génériques basées sur les classes.
Par exemple, dans votre views.py
:
import models
from Django.views.generic import ListView
class CarListView(ListView):
model = models.Car # shorthand for setting queryset = models.Car.objects.all()
template_name = 'app/car_list.html' # optional (the default is app_name/modelNameInLowerCase_list.html; which will look into your templates folder for that path and file)
context_object_name = "car_list" #default is object_list as well as model's_verbose_name_list and/or model's_verbose_name_plural_list, if defined in the model's inner Meta class
paginate_by = 10 #and that's it !!
Dans votre modèle (car_list.html
), vous pouvez inclure une section de pagination comme celle-ci (certaines variables de contexte sont disponibles: is_paginated
, page_obj
et paginator
).
{# .... **Normal content list, maybe a table** .... #}
{% if car_list %}
<table id="cars">
{% for car in car_list %}
<tr>
<td>{{ car.model }}</td>
<td>{{ car.year }}</td>
<td><a href="/car/{{ car.id }}/" class="see_detail">detail</a></td>
</tr>
{% endfor %}
</table>
{# .... **Now the pagination section** .... #}
{% if is_paginated %}
<div class="pagination">
<span class="page-links">
{% if page_obj.has_previous %}
<a href="/cars?page={{ page_obj.previous_page_number }}">previous</a>
{% endif %}
<span class="page-current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
<a href="/cars?page={{ page_obj.next_page_number }}">next</a>
{% endif %}
</span>
</div>
{% endif %}
{% else %}
<h3>My Cars</h3>
<p>No cars found!!! :(</p>
{% endif %}
{# .... **More content, footer, etc.** .... #}
La page à afficher est indiquée par un paramètre GET, en ajoutant simplement ?page=n
à l'URL.
supposons que j'ai une classe dans app/models.py nommée FileExam(models.Model)
:
app/models.py
class FileExam(models.Model):
myfile = models.FileField(upload_to='documents/%Y/%m/%d')
date = models.DateTimeField(auto_now_add=True, blank=True)
teacher_name = models.CharField(max_length=30)
status = models.BooleanField(blank=True, default=False)
app/views.py
from app.models import FileExam
from Django.core.paginator import Paginator
from Django.core.paginator import EmptyPage
from Django.core.paginator import PageNotAnInteger
class FileExamListView(ListView):
model = FileExam
template_name = "app/exam_list.html"
paginate_by = 10
def get_context_data(self, **kwargs):
context = super(SoalListView, self).get_context_data(**kwargs)
list_exam = FileExam.objects.all()
paginator = Paginator(list_exam, self.paginate_by)
page = self.request.GET.get('page')
try:
file_exams = paginator.page(page)
except PageNotAnInteger:
file_exams = paginator.page(1)
except EmptyPage:
file_exams = paginator.page(paginator.num_pages)
context['list_exams'] = file_exams
return context
seulement un petit changement dans le get_context_data
et le code de pagination ajouté à partir de la documentation Django ici
app/templates/app/exam_list.html
liste de contenu normale
<table id="exam">
{% for exam in list_exams %}
<tr>
<td>{{ exam.myfile }}</td>
<td>{{ exam.date }}</td>
<td>.....</td>
</tr>
{% endfor %}
</table>
paginer la section
{% if is_paginated %}
<ul class="pagination">
{% if page_obj.has_previous %}
<li>
<span><a href="?page={{ page_obj.previous_page_number }}">Previous</a></span>
</li>
{% endif %}
<li class="">
<span>Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.</span>
</li>
{% if page_obj.has_next %}
<li>
<span><a href="?page={{ page_obj.next_page_number }}">Next</a></span>
</li>
{% endif %}
</ul>
{% else %}
<h3>Your File Exam</h3>
<p>File not yet available</p>
{% endif %}
app/urls.py
urlpatterns = [
url(
r'^$', views.FileExamListView.as_view(), name='file-exam-view'),
),
... ]
Nous avons 2 méthodes pour le faire.
Le premier est simple et il suffit de définir le champ de classe paginate_by
. Nous n'avons rien à faire avec la méthode get_context_data
.
La seconde méthode est un peu compliquée, mais nous pouvons mieux comprendre la pagination et personnaliser la pagination complexe ou plusieurs paginations. Voyons ça.
Cela peut être fait en trois étapes.
get_context_data
de votre View
.Passez page_keys
et pages
afin que nous puissions parcourir les listes et éviter de coder en dur.
def get_context_data(self, *, object_list=None, **kwargs):
context = super().get_context_data()
df = pd.DataFrame(list(self.model.objects.all().values()))
ipc = df.groupby('ip')['ip'].count().sort_values(ascending=False)
urlc = df.groupby('url')['url'].count().sort_values(ascending=False).to_dict()
ipc = Tuple(ipc.to_dict().items())
urlc = Tuple(urlc.items())
pages = []
page_keys = ['page1', 'page2']
for obj, name in Zip([urlc, ipc], page_keys):
paginator = Paginator(obj, 20)
page = self.request.GET.get(name)
page_ipc = obj
try:
page_ipc = paginator.page(page)
except PageNotAnInteger:
page_ipc = paginator.page(1)
except EmptyPage:
page_ipc = paginator.page(paginator.num_pages)
pages.append(page_ipc)
context['data'] = Zip(pages, page_keys)
return context
template
.Nous définissons certaines variables pour pouvoir parcourir la liste de pagination.
pagination.html
{% if is_paginated %}
<ul class="pagination">
{% if page_obj.has_previous %}
<li>
<span><a href="?{{ pname }}={{ page_obj.previous_page_number }}">Previous</a></span>
</li>
{% endif %}
<li class="">
<span>Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.</span>
</li>
{% if page_obj.has_next %}
<li>
<span><a href="?{{ pname }}={{ page_obj.next_page_number }}">Next</a></span>
</li>
{% endif %}
</ul>
{% else %}
<h3>Your File Exam</h3>
<p>File not yet available</p>
{% endif %}
template
.index.html
{% for foo,name in data %}
<div class="col-md-3 table-responsive">
{% for k,v in foo %}
<tr>
<th>{{ forloop.counter }}</th>
<td>{{ k }}</td>
<td>{{ v }}</td>
</tr>
{% endfor %}
{% include 'pagination.html' with pname=name page_obj=foo %}
</div>
{% endfor %}