이번엔 CBV, Class Based View 라는거로 해볼 것이다. pagination을 여러데서도 반복핧 것이기에 이를 하나로 만들어서 상속시킬 것이다. 장고가 미리 만들어둔 클라스가 많기 때문에 이것을 이용할 것이다.
rooms - views.py
from django.views.generic import ListView
from . import models
class HomeView(ListView):
pass
core의 urls.py에는 views에 있는 all_rooms를 참조하라고 써놨는데 이게 없으니 에러가 뜬다. 가서 고쳐주자.
core - urls.py
from django.urls import path
from rooms import views as room_views
app_name = "core"
urlpatterns = [path("", room_views.HomeView, name="home")]
HomeView라고 쓰지 말고 HomeView.as_view()라고 쓰라고 한다.
이제 쿼리셋이 없다는 문구가 뜬다. HomeView.model, HomeView.queryset을 정의하거나 HomeView.get_queryset()을 재정의하라고 한다.
rooms - views.py
class HomeView(ListView):
"""HomeView Definition"""
model = models.Room
템플릿이 없다. ListView가 자동으로 앱 내의 템플릿을 뒤져보는데 이게 없다고 나오는 것이다. ListView가 선호하는 이름은 room_list.html 이므로 이에 맞게 고쳐주자.
https://docs.djangoproject.com/en/4.0/topics/class-based-views/mixins/
올ㅋ
ListView는 object_list에 접근한다. room_list.html을 이에 맞는 형식으로 바꿔주자.
{% for room in object_list %}
<h1>{{room.name}} / ${{room.price}}</h1>
{% endfor %}
이제 목록이 잘 뜬다.
ListView에 대한 추가적인 정보는 CCBV라는 사이트를 확인해보자. 여러 요소들이 있는데 그 중 paginate_by라는걸 써보자.
https://ccbv.co.uk/projects/Django/4.0/django.views.generic.list/ListView/
이 중 몇 가지를 써보자.
claass HomeView(ListView):
"""HomeView Definition"""
model = models.Room
paginate_by = 10
paginate_orphans = 5
ordering = "created"
page_kwarg = "potato"
paginate_by : 한 페이지에 올라오는 모델 갯수를 10개로 설정
paginate_orphans : 독립된 페이지 나누는 기준
ordering : 정렬 기준
page_kwarg : url에서 페이지를 의미하는 키워드
보면 자동으로 다른 페이지도 설정이 되어있고 url에 페이지 키워드가 potato로 등록되어있는 것을 볼 수 있다.
또한 마지막 페이지로 가보면 orphans 기준으로 인해 한 페이지에 12개가 들어와 있는 것을 볼 수 있다.
paginator 클래스도 가져올 수 있는데 이 경우 page_obj라는걸 쓸 수 있다. (일단 이 page_obj가 클래스 내에 구체적으로 명시가 된건 아직 못찾았다)
저대로 html 코드를 고쳐주자. page는 page_obj로, 그리고 url에 들어가는 keyword는 앞서 설정한대로 potato로 고친다.
templates - rooms - room_list.html
<h5>
{% if page_obj.has_previous %}
<a href="?potato={{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="?potato={{page_obj.next_page_number}}">Next</a>
{% endif %}
</h5>
짠. 버튼도 잘 살아났고 잘 동작한다.
아무튼 potato는 원래 page로 다시 바꿔주자.
그리고 context_object_name도 "rooms"로 해주자. 이거는 앞서 object_list로 설정되어있던걸 다른 이름으로 바꾸게 해준다.
rooms - views.py
class HomeView(ListView):
"""HomeView Definition"""
model = models.Room
paginate_by = 10
paginate_orphans = 5
ordering = "created"
context_object_name = "rooms"
templates - rooms - room_list.html
...
{% for room in rooms %}
<h1>{{room.name}} / ${{room.price}}</h1>
{% endfor %}
...
그리고 context를 추가해볼 것이다.
rooms - views.py - HomeView
...
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
now = timezone.now()
context["now"] = now
return context
그리고 템플릿에는 block context 내부에 {{now}} 를 아무데나 추가하자.
현재 시간이 표시된 것을 볼 수 있다.
이건 연습이었으니 없애고 원상복구한다.