글이 여러개라면, 화면에 끝도없이 나타날 것이므로 페이징의 필요하다.
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|를 통해 만들었다.
정신나갈것같다.