Django 프로젝트-To Do List(4): GenericView - ListView, DetailView
1. ListView 구현
이제 본격적으로 생성한 모델을 화면에 출력해보자. 모델을 화면에 출력하기 위한 뷰 작성법은 함수형 뷰와 리스트형 뷰가 있다. 각각 장단점이 존재하는데 나는 쉽게 구현할 수 있는 클래스뷰를 통해 모델을 출력해보고자 한다.
먼저 구현할 뷰는 리스트뷰이다. 리스트뷰는 모델을 가져와서 리스트로 표시하는 것이다(Ex. 게시판 글). 리스트뷰를 사용하기 위해서 클래스뷰를 선언해주어야 한다. 그 다음 클래스뷰를 사용하기 위해서는 해당 클래스뷰를 상속받아야 한다. 뷰를 상속받으면 이제 클래스뷰의 기능을 사용할 수 있다. 일단 모델을 가져와야 하기 때문에 model을 정해준다.
# task/views.py
from django.views.generic.list import ListView
from .models import Task
class TaskList(ListView):
model = Task
뷰를 만들었으니 이제 url을 연결해주어야 한다. 뷰를 하나 만들면 꼭! url을 연결해주어야 하는 것을 잊지 말자. 먼저 모델을 임포트하고 url을 입력해준다. 여기서 중요한 것은 함수형 뷰와 다르게 클래스형 뷰는 뷰의 이름 뒤에 꼭! .as_views()를 붙여주어야 한다.
# task/urls.py
from .views import TaskList
urlpatterns = [
path('', TaskList.as_view(), name="tasks"),
]
이제 템플릿을 만들어야할 차례이다. 템플릿 파일을 만들 때 중요한 것은 각 앱에 templates 폴더를 만들고 그 안에 또 앱의 이름을 가진 폴더를 만들어야 한다는 것이다(task/templates/task). 이렇게 해야 유지보수가 쉬워진다.
클래스형 뷰는 각 뷰에 할당되는 디폴드 템플릿 이름이 있다. 리스트뷰는 앱이름_list으로 지정되어있다. 여기서는 task_list.html로 템플릿을 만들면 된다. 템플릿 파일을 만들었다면 이제 본격적으로 화면에 모델을 출력하기 위한 템플릿을 작성해보자.
템플릿에서 모델을 출력하기 위해서는 템플릿 태그를 사용해야 한다. 간단하게 살펴보면 {{ }}로 변수를, {% %}로 함수를 표현한다. 그리고 또한 중요한 것은 아까 템플릿 파일의 이름처럼 템플릿 변수 또한 기본 이름이 정해져있다. object_list나 앱이름_list로 사용하면 된다.
하지만 이러한 이름은 직관적이지 않을 수 있기 때문에 보통 이름을 바꾸어서 사용한다. 바꾸는 방법은 다음과 같이 뷰에 context_object_name를 지정해주면 된다.
# task/views.py
class TaskList(ListView):
model = Task
context_object_name = 'tasks'
이제 템플릿 파일을 작성해보자. 함수는 대부분 기본 파이썬 문법과 비슷하지만 함수가 끝날 때는 꼭 {% end함수이름 %}로 끝내야한다. 또한 {% empty %}는 많이 쓰는 함수이므로 기억해두자!
<!--task/templates/task/task_list.html-->
<h1>My to do list</h1>
<table>
<tr>
<th>Items</th>
</tr>
{% for task in tasks %}
<tr>
<td>{{ task.title }}</td>
<td><a href="">View</a> </td>
</tr>
{% empty %}
<h1>No items in list</h1>
{% endfor %}
</table>
2. DetailView 작성
이제 리스트뷰를 모두 작성했으니 각 모델을 하나 씩 확인할 수 있는 디테일뷰를 작성해보자. 둘은 보통 같이 쓰이니 한 번에 잘 알아두자.
기본 준비과정은 리스트뷰와 동일하다. 뷰를 작성하고, url을 연결하고, 템플릿 파일을 작성한다.
# task/views.py
from django.views.generic.detail import DetailView
class TaskDetail(DetailView):
model = Task
context_object_name = 'task'
template_name = 'task/task.html'
# task/urls.py
urlpatterns = [
path('', TaskList.as_view(), name="tasks"),
path('task/<int:pk>/', TaskDetail.as_view(), name="task"),
]
<!--task/templates/task/task.html-->
<h1>Task: {{ task }}</h1>
리스트뷰와 다른 몇 가지를 살펴보면 뷰에 template_name = ‘task/task.html’을 추가했다. 이는 기본 템플릿 이름을 바꿀 수 있게 해준다. url에서도 살짝 다른데, 주소에 task/<int:pk>/가 있다. 이는 모델 각각에 접근하기 위해 pk값을 추가해준 것이다.
이제 마지막으로 디테일뷰로 진입할 수 있는 링크를 만들어보자. url을 연결시키기 위해서는 {% url %}을 활용한다. url은 urls.py에서 지정해준 name으로 연결하면 된다.
<!--task/templates/task/task_list.html-->
<h1>My to do list</h1>
<table>
<tr>
<th>Items</th>
</tr>
{% for task in tasks %}
<tr>
<td>{{ task.title }}</td>
<td><a href="{% url 'task' task.id %}">View</a> </td>
</tr>
{% empty %}
<h1>No items in list</h1>
{% endfor %}
</table>
핵심요약
- 뷰 -> url -> 템플릿
- 템플릿 폴더 앱/templates/앱이름
- listview 디폴트 템플릿 이름: 앱이름_list.html -> template_name
listview 디폴트 템플릿 변수 이름: 앱이름_list or object_list -> context_object_name- detailview 디폴트 템플릿 이름: 앱이름_detail.html
detailview 디폴트 템플릿 변수 이름: 앱이름_detail or object_detail- detailview url: <int:pk/>, 앱이름.id
Leave a comment