Câu trả lời:
Tôi nghĩ rằng bạn hỏi thông tin về việc sử dụng phân trang với các khung nhìn dựa trên lớp mới vì, với các khung nhìn dựa trên chức năng truyền thống, rất dễ tìm thấy. Tôi thấy rằng chỉ bằng cách đặt paginate_by
biến là đủ để kích hoạt phân trang. Xem trong các khung nhìn chung dựa trên lớp .
Ví dụ: trong 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 !!
Trong mẫu của bạn ( car_list.html
), bạn có thể bao gồm một phần pagination như thế này (chúng tôi có một số biến bối cảnh có sẵn: is_paginated
, page_obj
, và 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.** .... #}
Trang để hiển thị được biểu thị bằng tham số GET, chỉ cần thêm ?page=n
vào URL.
giả sử, tôi có một lớp trong app / model.py có tên FileExam(models.Model)
:
ứng dụng / mô hình
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)
ứng dụng / lượt xem
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
chỉ có một chút thay đổi trong get_context_data
và thêm mã phân trang từ tài liệu django ở đây
ứng dụng / mẫu / ứng dụng / tests_list.html
danh sách nội dung bình thường
<table id="exam">
{% for exam in list_exams %}
<tr>
<td>{{ exam.myfile }}</td>
<td>{{ exam.date }}</td>
<td>.....</td>
</tr>
{% endfor %}
</table>
phần phân trang
{% 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 %}
ứng dụng / url
urlpatterns = [
url(
r'^$', views.FileExamListView.as_view(), name='file-exam-view'),
),
... ]
context = super(SoalListView, self)...
. Ý bạn là context = super(FileExamListView, self)...
sao?
Chúng tôi có 2 phương pháp để làm điều này.
Đầu tiên là đơn giản và chỉ cần thiết lập trường lớp paginate_by
. Không có gì chúng ta cần phải làm với get_context_data
phương pháp.
Phương pháp thứ hai hơi phức tạp nhưng chúng ta có thể hiểu rõ hơn về phân trang và tùy chỉnh phân trang phức tạp hoặc một số phân trang. Chúng ta hãy xem nó.
Nó có thể được thực hiện trong ba bước.
get_context_data
Phương pháp 1.Override của bạn View
.Vượt qua page_keys
và pages
để chúng ta có thể lặp lại các danh sách và tránh mã hóa cứng.
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
.Chúng tôi xác định một số biến để chúng tôi có thể lặp qua danh sách phân trang.
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 %}