Django 클래스 기반 일반 ListView에서 페이지 매김을 어떻게 사용합니까?


183

Django 1.3에서 페이지 매김을 어떻게 사용합니까?

이에 대한 문서는 명확하지 않습니다.

  • 나의 것은 무엇입니까 views.py?

  • 템플릿은 어떻게 되나요?

  • URLconf 파일은 어떻게됩니까?

답변:


338

전통적인 함수 기반 뷰를 사용하면 쉽게 찾을 수 있기 때문에 새로운 클래스 기반 뷰에서 페이지 매김 사용에 대한 정보를 요청한다고 생각합니다. paginate_by변수 를 설정하는 것만으로 페이지 매김을 활성화하기에 충분 하다는 것을 알았습니다 . 클래스 기반 일반 뷰를 참조하십시오 .

예를 들어,에 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 !!

템플릿 ( car_list.html)에 다음과 같은 페이지 매김 섹션을 포함 할 수 있습니다 (사용 가능한 컨텍스트 변수 is_paginatedpage_obj,, 및 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.** .... #}

표시 할 페이지 ?page=n는 URL에 단순히을 추가하여 GET 매개 변수로 표시됩니다 .


1
괜찮습니다.하지만 템플릿을 어떻게 묶어 "car_list"객체를 볼 수 있습니까?
gath

28
참고로 urls.py:url(r'^cars/$ ', ListView.as_view (model = Car, paginate_by = 10))에서 직접 할 수도 있습니다.
shawnwall

내가 배운 교훈 : 방법을 찾고, 새로운 탭에서 모든 조상 클래스를 열고, CTRL + F를 핵심 단어에서 멀리하십시오. 그래서docs.djangoproject.com/en/dev/ref/class-based-views/… 찾을 수 있습니다. 기본 자습서에서 존재하는 것으로 알고 있으며 모든 조상 링크를 열고 "pagi"를 검색하십시오
Ciro Santilli

2
이 작업을 수행했지만 쿼리 세트의 객체에 대해 추가 처리를 수행하면 데이터베이스의 모든 결과에 적용됩니다. 따라서 100 개의 개체를 반환하지만 페이지 당 10 개의 개체 만 표시하는 쿼리의 경우 100 개의 개체에 대해 추가 처리가 수행됩니다.
wobbily_col

32
<a href="?page={{ page_obj.previous_page_number }}"> 이전 </a>
dalore

42

app / models.py에 다음과 같은 클래스가 있다고 가정합니다 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(FileExamListView, 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

get_context_data장고 문서의 페이지 매김 코드 가 조금만 변경되고 여기에 추가되었습니다.

app / templates / app / exam_list.html

일반 컨텐츠 목록

<table id="exam">
  {% for exam in list_exams %}
  <tr>
    <td>{{ exam.myfile }}</td>
    <td>{{ exam.date }}</td>
    <td>.....</td>
  </tr>
  {% endfor %}
</table>

페이지 매김 섹션

{% 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'),
), 
... ]

1
이것은 올바르게 보이지 않습니다 : context = super(SoalListView, self).... 당신은 의미 했습니까 context = super(FileExamListView, self)...?
cezar

네, 그러죠! 이 답변은 Mr. Yacin이 편집했습니다. 감사합니다, 야신 씨
Yanwar Sky

1

이를위한 두 가지 방법이 있습니다.

첫 번째는 간단하고 클래스 필드를 설정하는 것입니다 paginate_by. 우리는 get_context_data방법 과 관련이 없습니다 .

두 번째 방법은 약간 복잡하지만 페이지 매김에 대한 이해도를 높이고 복잡한 페이지 매김 또는 여러 페이지 매김을 사용자 지정할 수 있습니다. 어디 보자.

세 단계로 수행 할 수 있습니다.

1.의 재정의 get_context_data방법 View.

통과 page_keys하고 pages그래서 우리는 목록을 반복하고 하드 코딩 피할 수있다.

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

2. 서브 커스터마이즈 template .

페이지 매김 목록을 반복 할 수 있도록 일부 변수를 정의합니다.

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 %}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.