Generic 뷰 사용하기
적은 코드가 낫다
Part3 에서 detail() 과 results() 뷰들은 매우 짧지만, 중복이 됩니다.
index() 뷰도 비슷하고, 투표 리스트를 출력합니다.
이 뷰들은 공통적인 기본 웹개발 방법을 대표합니다.
- URL 에서 전달된 파라미터에 따라서 데이터를 데이터베이스에서 가져오고
- 템플릿을 읽고 처리된 템플릿을 반환합니다
이것은 매우 공통된 부분이기 때문에, 이것을 쉽게 다룰수 있는 generic view 시스템을 Django 가 제공합니다.
왜 GenericView 인가?
Generic view 는 웹개발에서 공통된 패턴들에 대해서
더이상 파이썬 코드들을 쓸 필요가 없는 지점까지 추상화 합니다.
튜토리얼에서 작업하고 있었던 polls 앱을 generic view 를 사용하도록 전환 해 봅시다.
몇가지 코드를 지우고도 사용할수 있게 됩니다! 전환을 위해서 다음 스텝들을 거쳐 갑니다.
- URLConf 바꾸기
- 불필요하고 오래된 코드 삭제하기
- Django 의 genericview 를 기반으로 하는 새로운 코드 쓰기
왜 코드를 다시 작업하는가?
보통 Django 앱을 작성할때에는,
generic view 를 사용하는것이 문제 해결에 도움이 되는지에 대해 먼저 파악 합니다.
코드를 중간에 리펙토링 하지 않고, 처음부터 generic view 를 사용합니다.
튜토리얼에서는, 단지 의도적으로 주요 컨셉에 집중하기 위해서
어려운 방식으로 뷰를 작성 했었던것 뿐입니다.
Generic view 로 전환
Views 수정하기
index, detail 그리고 results 뷰들의 오래된 코드들을 삭제하고, django 의 generic view 를 사용해 봅니다. generic view 를 사용하기 위해서, polls/views.py 파일을 열고, 아래와 같이 코드를 바꾸어 줍니다.
polls/views.py 파일을 열고, 아래 뷰들을 수정해 줍니다.
index()
detail()
results()
vote() 는 수정해 주지 않습니다.
1 | from django.http import HttpResponseRedirect |
여기서 우리는 두개의 generic view 를 사용합니다. ListView 와 DetailView 입니다.
ListView 는 “모든 객체의 리스트를 출력하기”
DetailView 는 “디테일 페이지 출력하기”
이 두가지 아이디어를 요약 하여, genericview 가 만들어 졌습니다.
- 각 generic view 들은 어떤 모델을 사용해서 작동해야 할지 알아야 합니다. 이것은 model 속성들 사용에 의해서 주어집니다.
- DetailView 는 URL 에서 켑쳐된 Primary Key 를 기대하고 있기 때문에, question_id 를 pk 로 바꿔줍니다.
DetailView
기본값으로 DetailView
는 <appname>/<model name>_detail.html
템플릿 형태를 사용합니다. 튜토리얼 예시에서는 “polls/question_detail.html” 템플릿을 사용할것 입니다.
하지만, 이번 튜토리얼에서는 template_name = “polls/detail.html” 을 둠으로써,
기존에 만든 템플릿을 사용하게 하였습니다.
template_name 속성은,
기본으로 정해진 템플릿명 대신에 django에게 특정 템플릿 이름을 사용하게 합니다.
template_name 속성을 results 리스트 뷰에도 명시하여,
기존에 사용했던 results view 와 detail view 가 화면에 출력 될때, 다르게 render 되게 만듭니다.
이렇게 되면 두 뷰가 같은 DetailView 라고 해도, 다르게 표시가 됩니다.
ListView
비슷한 맥락으로, ListView 는 기본 템플릿으로 <app name>/<model name>_list.html
을 사용합니다.
하지만, 우리는 tempalte_name = ‘polls/index.html’ 템플릿으로 명시를 해줌으로써,
ListView 가 기존에 있던 ‘polls/index.html’ 템플릿을 사용하도록 설정해줍니다.
이전 튜토리얼 과정에서, 템플릿들은 question 과 lastest_question_list 컨텍스트 변수들을 가지고 있는 컨텍스트들을 전달 받았었습니다.
DetailView 는 question 변수가 자동으로 주어집니다. 이것은 모델명을 기반으로 가져오는것이라,
자동으로 DetailView 가 적절한 컨텍스트 변수명을 판단하여 가져옵니다.
ListView 에 context 변수명 속성을 명시해 줍니다
context_object_name = latest_question_list
ListView는 기본적으로 자동으로 생성하는 컨텍스트 변수명은 question_list 입니다. 이 context 변수명을 명시를 해주기 위해서,
context_object_name 속성을 지정해 줍니다.
context_object_name 을 지정해주고 싶지 않다면, 그냥 템플릿에서 context 변수명들을 바꾸어 주면 됩니다.
URL 세팅해주기
views.py 에 있는 뷰들이 generic view 들인 클래스 뷰들로 바뀌었습니다.
vote 를 제외한 index, detail 그리고 results 뷰들이 바뀌었고. 이것들이 url 에서 호출되도록 변경해주어야 합니다.
polls/urls.py 파일을 열어서, index, detail 그리고 results 뷰에 대한 URL설정을 고쳐줍니다.
1 | from django.urls import path |
IndexView, DetailView 그리고 ResultsView 는
클래스 기반의 generic view 입니다.
이 뷰들을 URL에서 호출하려면,
view 뒤에 as_view() 함수를 붙여줘야 잘 작동합니다.
그리고, int:question_id 를 int:pk 로 바꾸어줘야 작동합니다.
왜냐하면, DetailView 는 pk 를 인자로 받기 때문입니다.
서버를 시작하고, 한번 시험해 봅니다. IndexView 호출
![](/2020/04/30/Writing-your-first-Django-app-part4-2%ED%8E%B8/image1.png)
DetailView 호출
![](/2020/04/30/Writing-your-first-Django-app-part4-2%ED%8E%B8/image2.png)
ResultsView 호출
![](/2020/04/30/Writing-your-first-Django-app-part4-2%ED%8E%B8/image3.png)
마치며..
사전 지식 없이 튜토리얼만 보고 공부 시작했다가 낭패 봤습니다.
겨우겨우 찾아서, 클래스 기반의 뷰들을 작성 해보았지만.. 알아내기 힘들었습니다.
폼과 generic view 와 친숙해 졌으면, part5 로 넘어갑니다.