Skip to main content

3-2페이징

·655 words·4 mins· loading
Table of Contents

https://wikidocs.net/71240

글이 여러개라면, 화면에 끝도없이 나타날 것이므로 페이징의 필요하다.

views.py에

from django.core.paginator import Paginator 를 사용한다.

page = request.GET.get(‘page’, ‘1’)# get 방식으로 호출된 url에서 페이지를 가져올 때 사용한다. 호출값이 없을 땐 default로 1을 반환한다.

context로 page_obj = paginator.get_page(page)를 받게된다.

question_list.html의 페이징 코드이다.

    <!-- 페이징처리 시작 -->    <ul class="pagination justify-content-center">
        <!-- 이전페이지 -->        <li class="page-item">
            <a class="page-link" href="?page=1">처음</a>        </li>  
        {% if question_list.has_previous %}        <li class="page-item">
            <a class="page-link" href="?page={{ question_list.previous_page_number }}">이전</a>
        </li>        {% else %}        <li class="page-item disabled">
            <a class="page-link" tabindex="-1" aria-disabled="true" href="#">이전</a>
        </li>        {% endif %}        <!-- 페이지리스트 -->
        {% for page_number in question_list.paginator.page_range %}
        {% if page_number >= question_list.number|add:-3 and page_number <= question_list.number|add:3 %}
        {% if page_number == question_list.number %}
        <li class="page-item active" aria-current="page">
            <a class="page-link" href="?page={{ page_number }}">{{ page_number }}</a>
        </li>        {% else %}         <li class="page-item">
            <a class="page-link" href="?page={{ page_number }}">{{ page_number }}</a>
        </li>           {% endif %}
        {% elif page_number >= question_list.number|add:-4 and page_number <= question_list.number|add:4 %}
        <li class="page-item">...</li>        {% endif %}        {% endfor %}
        <!-- 다음페이지 -->        {% if question_list.has_next %}
        <li class="page-item">
            <a class="page-link" href="?page={{ question_list.next_page_number }}">다음</a>
        </li>        {% else %}        <li class="page-item disabled">
            <a class="page-link" tabindex="-1" aria-disabled="true" href="#">다음</a>
        </li>        {% endif %}        <li class="page-item">
        <a class="page-link" href="?page={{ max_index }}">마지막</a>    </li>  
</ul>    <!-- 페이징처리 끝 -->

이걸 이해할려고 하다가 너무 답답해서 쓴다.

먼저, {% if question_list.has_previous를 %} 통하여, 이전페이지가 있으면 이전 버튼을 활성화/비활성화한다.

그후,

question_list.paginator.page_range는, 말그대로 모든 페이지 범위를 range로 가지고있다. #range(1,32)

{% for page_number in question_list.paginator.page_range %} 를 통하여, page는 숫자를 가지게 된다.

{% if page_number >= question_list.number|add:-3 and page_number <= question_list.number|add:3 %}

iquestion_list.number|add:3 의 뜻은, question_list+3이다.
#

반복문으로 page를 1부터 돌거다.

만일 page가 현재 페이지의 번호랑 절댓값 3이상의 차이면, 나타내라는 뜻이다. 이게 너무 헷갈렸다.

전체코드

pybo/views.py

from django.shortcuts import render,get_object_or_404,redirect
from django.utils import timezone
from django.http import HttpResponse, HttpResponseNotAllowedfrom . import models
from .forms import QuestionForm,AnswerForm
from django.core.paginator import Paginator# Create your views here.
def index(request):    page=request.GET.get('page','1')
    question_list=models.Question.objects.order_by('-create_data')
    pagintor=Paginator(question_list,10)    page_obj=pagintor.get_page(page)
    context={'question_list':page_obj,'max_index':len(pagintor.page_range)}
    return render(request,'pybo/question_list.html',context)
def detail(request,question_id):
    # question=models.Question.objects.get(id=question_id)
    question=get_object_or_404(models.Question,pk=question_id)
    context={'question':question}
    return render(request, 'pybo/question_detail.html',context)
def answer_create(request,question_id): #답변등록
    question=get_object_or_404(models.Question,pk=question_id)
    if request.method=='POST':        form = AnswerForm(request.POST)
        if form.is_valid():            answer=form.save(commit=False)
            answer.create_data=timezone.now()
            answer.question=question            answer.save()
            return redirect('pybo:detail',question_id=question_id)    else:
        return HttpResponseNotAllowed('Only POST')
    context={'question':question,'form':form}
    return render(request,'pybo/question_detail.html',context)
    # question=get_object_or_404(models.Question,pk=question_id)
    # question.answer_set.create(content=request.POST.get('content'), create_data=timezone.now())
    # # answer=models.Answer(question=question,content=request.POST.get('content'),create_data=timezone.now())
    # # answer.save()
    # return redirect('pybo:detail',question_id=question.id)
def question_create(request):    if request.method=="POST":
        form=QuestionForm(request.POST)        if form.is_valid():
            question=form.save(commit=False)
            question.create_data=timezone.now()            question.save()
            return redirect('pybo:index')    else:        form=QuestionForm()
    context={'form':form}
    return render(request,'pybo/question_form.html',context)

question_detail.html

{% extends 'base.html' %}{% block content %}<div class="container my-3">
    <table class="table">        <thead>        <tr class="table-dark">
            <th>번호</th>            <th>제목</th>            <th>작성일시</th>
        </tr>        </thead>        <tbody>        {% if question_list %}
        {% for question in question_list %}        <tr>
            <td>{{ forloop.counter }}</td>            <td>
                <a href="{% url 'pybo:detail' question.id %}">{{ question.subject }}</a>
            </td>            <td>{{ question.create_data }}</td>        </tr>
        {% endfor %}        {% else %}        <tr>
            <td colspan="3">질문이 없습니다.</td>        </tr>        {% endif %}
        </tbody>    </table>    <!-- 페이징처리 시작 -->
    <ul class="pagination justify-content-center">        <!-- 이전페이지 -->
        <li class="page-item">
            <a class="page-link" href="?page=1">처음</a>        </li>  
        {% if question_list.has_previous %}        <li class="page-item">
            <a class="page-link" href="?page={{ question_list.previous_page_number }}">이전</a>
        </li>        {% else %}        <li class="page-item disabled">
            <a class="page-link" tabindex="-1" aria-disabled="true" href="#">이전</a>
        </li>        {% endif %}        <!-- 페이지리스트 -->
        {% for page_number in question_list.paginator.page_range %}
        {% if page_number >= question_list.number|add:-3 and page_number <= question_list.number|add:3 %}
        {% if page_number == question_list.number %}
        <li class="page-item active" aria-current="page">
            <a class="page-link" href="?page={{ page_number }}">{{ page_number }}</a>
        </li>        {% else %}         <li class="page-item">
            <a class="page-link" href="?page={{ page_number }}">{{ page_number }}</a>
        </li>           {% endif %}
        {% elif page_number >= question_list.number|add:-4 and page_number <= question_list.number|add:4 %}
        <li class="page-item">...</li>        {% endif %}        {% endfor %}
        <!-- 다음페이지 -->        {% if question_list.has_next %}
        <li class="page-item">
            <a class="page-link" href="?page={{ question_list.next_page_number }}">다음</a>
        </li>        {% else %}        <li class="page-item disabled">
            <a class="page-link" tabindex="-1" aria-disabled="true" href="#">다음</a>
        </li>        {% endif %}        <li class="page-item">
        <a class="page-link" href="?page={{ max_index }}">마지막</a>    </li>  
</ul>    <!-- 페이징처리 끝 -->
    <a href="{% url 'pybo:question_create' %}" class="btn btn-primary">질문 등록하기</a>
</div>{% endblock %}

책에 안나와있는 처음,끝으로 가기와 …까지 구현해봤다.

처음으로 가는 버튼은 href="?page=1"버튼을 만들면 되고,

끝으로 가는 버튼은 views.py에서 context에 max_index하나를 추가해 page={{max_index}}로 가게 만들면 된다

#len(paginator.get_page)

…을 구현하는 것은

앞서 설명한 {% if page_number >= question_list.number|add:-3 and page_number <= question_list.number|add:3 %}

에 대한 elif 구문을 만들고, |3|이 아닌 |4|를 통해 만들었다.

정신나갈것같다.