지난 포스팅에 이어서 많은 방들의 리스트를 페이지로 나눌 것인데, 함수 기반 뷰(Funtion Based Views)와 클래스 기반 뷰(Class Based Views) 두가지 방법을 통해 웹 페이지를 제작해보려고 한다.
2020/11/13 - [Python/Django] - [Django] 장고 템플릿 #2
함수 기반 뷰(Funtion Based Views) : 직접 함수를 작성하여 request 처리
논리적으로 직접 코딩하는 방법도 있지만 Paginator라는 모듈을 이용해서 간단하게 함수 기반 뷰 페이지를 만들어보려고 한다.
views.py파일은 아래와 같다.
from django.shortcuts import render, redirect
from django.core.paginator import Paginator, EmptyPage
from . import models
def all_rooms(request):
page = request.GET.get("page", 1)
room_list = models.Room.objects.all()
paginator = Paginator(room_list, 10, orphans=5)
try:
rooms = paginator.page(int(page))
return render(request, "rooms/home.html", {"page": rooms})
except EmptyPage:
return redirect("/")
- request.GET.get("page",1)은 url의 query string에서 "page" 에 해당하는 값을 가져온다. 단 page값이 존재하지 않을 경우 default값은 1로 셋팅한다.
- Paginator(쿼리셋, 페이지 당 보여질 목록 개수)를 호출하면 Paginator라는 객체가 생성된다.
※orpahans = 5로 설정해준다면 5이하일 때 이전 페이지로 넘겨준다.
- Paginator 객체는 page(페이지번호)를 통해 해당하는 페이지에 보여질 objects들을 쿼리셋형태로 반환한다.
또 except EmptyPage를 설정해주었는데 빈 페이지가 호출되면 "/"로 redirect 시킨다.
템플릿 파일은 아래와 같이 설정해주었다.
{% extends "base.html" %}
{% block page_name %}
Home
{% endblock page_name %}
{% block content %}
{% for room in page.object_list %}
<h1>{{room.name}} / ${{room.price}}</h1>
{% endfor %}
<h5>
{% if page.has_previous %}
<a href="?page={{page.previous_page_number}}">Previous</a>
{% endif %}
Page {{page.number}} of {{page.paginator.num_pages}}
{% if page.has_next %}
<a href="?page={{page.next_page_number}}">Next</a>
{% endif %}
</h5>
{% endblock content %}
클래스 기반 뷰(Class Based Views) : 클래스를 상속받아 작성
함수 기반 뷰에서는 함수내에서 정의했지만 클래스 기반 뷰에서는 ListView를 상속받아 아래와 같이 간단하게 작성가능하다.
from django.utils import timezone
from django.views.generic import ListView
from . import models
class HomeView(ListView):
""" HomeView Definition """
model = models.Room
paginate_by = 10
pasinate_orphans = 5
ordering = "created"
context_object_name = "rooms"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
now = timezone.now()
context["now"] = now
return context
위 처럼 model을 정의해주고 pasinate_by는 한 페이지에 들어 갈 데이터 개수, pasinate_orphans를 5로 설정해주면 개수가 5개 이하일 때 그 전 페이지로 데이터를 넘겨준다. 정렬도 할 수 있다. 이러한 기능은 ccbv.co.uk/ 아래 링크로 들어가보면 다양한 기능들을 확인 해 볼 수 있다.
템플릿 파일은 변수명만 수정하고 나머지는 같게 해주었다.
{% extends "base.html" %}
{% block page_name %}
Home
{% endblock page_name %}
{% block content %}
{{now}}
{% for room in rooms %}
<h1>{{room.name}} / ${{room.price}}</h1>
{% endfor %}
<h5>
{% if page_obj.has_previous %}
<a href="?page={{page_obj.previous_page_number}}">Previous</a>
{% endif %}
Page {{page_obj.number}} of {{page_obj.paginator.num_pages}}
{% if page_obj.has_next %}
<a href="?page={{page_obj.next_page_number}}">Next</a>
{% endif %}
</h5>
{% endblock content %}
※ urls.py 확인
클래스 기반 뷰의 장점은 클래스의 장점을 사용할 수 있다. 상속, 오버라이딩 등 여러 방식으로 코드의 효율을 극대화 할 수 있다. 하지만 이미 많은 부분이 정해져있다. 이는 장점으로 작용할 수 있지만 이미 정해져있는 부분들을 제대로 이해하고 있지 않는다면 이를 활용하기에 부족한 점이 많을 것이다. 또한 클래스의 상속 등과 같은 여러 파이썬 문법에 대한 선행 지식이 선행되어야 한다. 그러므로 함수 기반 뷰를 어느정도 숙지한 후 두가지 방법을 상황에 맞게 사용하는 것이 바람직하다고 생각한다.
'Web developer > Django' 카테고리의 다른 글
[Django] 카카오 로그인 (1) | 2020.12.24 |
---|---|
[Django] 함수 기반 뷰 vs. 클래스 기반 뷰 #DetailView (0) | 2020.11.14 |
[Django] 장고 템플릿 #2 (0) | 2020.11.13 |
[Django] 장고 템플릿 #1 (0) | 2020.11.13 |
[Django] 쿼리셋(Query sets) (0) | 2020.11.09 |
댓글