1. 정의

소프트웨어 디자인 패턴에서 뷰(View)는 웹 요청을 분석하고 DB 처리 등 필요한 로직을 수행하며 템플릿을 통해 화면에 표시할 데이터를 만들어서 최종 데이터를 클라이언트에게 응답하는 역할을 담당한다.

장고에서는 이러한 로직을 함수형 뷰 혹은 클래스형 뷰로 작성이 가능한데 차이점은 다음과 같다.

함수형 뷰 클래스형 뷰
구현이 상대적으로 빠르다 구현이 상대적으로 느리다
코드가 복잡해질수록 상대적으로 재사용성이 떨어진다 코드가 복잡해질수록 상대적으로 재사용성이 좋다(상속기능)

이외에도 클래스형 뷰에서는 제네릭 뷰와 페이징 처리, MF(Method Flowchart, 내부 처리 과정 가시화), MRO(Method Resolution Order, 다중 상속에서의 메소드 결정 순서) 등 다양한 기능들을 제공한다.

 

 

 

2. 제네릭 뷰(Generic View)

웹 프로그램 개발 시 공통적으로 사용하는 로직이 담긴 기본 클래스를 제공하는 장고의 기능.

제네릭 뷰 분류 제네릭 뷰 이름 뷰의 기능 및 역할
Base View View 가장 기본이 되는 최상위 제네릭 뷰. 아래의 모든 제네릭 뷰는 해당 뷰를 상속받는다.
TemplateView 템플릿이 주어질때 해당 템플릿을 렌더링한다.
RedirectView URL이 주어질 때 해당 URL로 리다이렉트 한다.
Generic Display View ListView 조건에 맞는 여러 개의 객체 리스트를 반환한다.(ex. 게시글 리스트 페이지)
DetailView 객체 하나에 대한 상세한 정보를 보여준다.(ex. 게시글 상세 페이지)
Generic Edit View FormView 폼이 주어질 때 해당 폼을 보여준다.
CreateView 폼을 보여주고 폼의 내용으로 DB 레코드를 신규 생성한다.
UpdateView 폼을 보여주고 폼의 내용으로 기존 DB 레코드를 수정한다.
DeleteView 삭제 컨펌 폼을 보여주고, 기존 DB 레코드를 삭제한다.
Generic Date View ArchiveView 조건에 맞는 여러 개의 객체 및 그 객체들에 대한 날짜 정보를 보여준다.
YearArchiveView 연도가 주어지면 그 연도에 해당하는 객체들을 보여준다.
MonthArchiveView 연, 월이 주어지면 그에 해당하는 객체들을 보여준다.
WeekArchiveView 연도 및 주(Week)가 주어지면 그에 해당하는 객체를 보여준다.
DayArchiveView 연, 월, 일이 주어지면 그 날짜에 해당하는 객체를 보여준다.
TodayArchiveView 오늘 날짜에 해당하는 객체들을 보여준다.
DateDetailView 연, 월, 일, 기본키(혹은 슬러그)가 주어지면 그에 대당하는 특정 객체 하나에 대한 상세한 정보를 보여준다.

 

 

 

3. 제네릭 뷰 오버라이딩

3-1. 속성 오버라이딩

장고로 개발할 때 제네릭 뷰에서 제공하는 속성들을 그대로 사용할건지 혹은 변경할건지 선택해야 하는데 여기서 후자가 될 경우 사용하는 것이 속성 오버라이딩이다.

속성명 설명
model View, TemplateView, RedirectView, FormView 4개를 제외하고 모든 제네릭 뷰에 사용하는 속성으로 작업 대상 데이터가 들어 있는 모델을 지정한다.
queryset View, TemplateView, RedirectView, FormView 4개를 제외하고 모든 제네릭 뷰에 사용하는 속성으로 작업 대상이 되는 QuerySet 객체를 지정한다.
template_name TemplateView를 포함한 모든 제네릭 뷰에서 사용하는 속성으로 템플릿 파일명을 문자열로 지정한다.
context_object_name View, TemplateView, RedirectView 3개를 제외하고 모든 제네릭뷰에 사용하는 속성으로 템플릿 파일에서 사용할 컨텍스트 변수명을 지정한다.
paginate_by ListView와 날짜 기반 뷰에서 사용한다. 페이징 기능이 활성화된 경우 한 페이지당 몇 개를 출력할지 정수로 지정한다.
date_field 날짜 기반 뷰에서 기준이 되는 필드를 지정한다. 해당 필드를 기준으로 연/월/일을 검사하는데, 이 때 타입은 DateField 혹은 DateTimeField여야 한다.
make_object_list YearArchiveView 사용시 해당 연도에 맞는 객체들의 리스트를 생성할지 여주를 지정한다. True면 객체들의 리스트를 만들어서 사용할 수 있고 False면 queryset 속성에 None이 할당된다.
form_class FormView, CreateView, UpdateView에서 사용하는 속성으로 폼을 만드는데 사용할 클래스를 지정한다.
initial FormView, CreateView, UpdateView에서 사용하는 속성으로 폼에 사용할 초기 데이터를 사전에 지정한다.
ex. { ... }
fields CreateView, UpdateView에서 사용하는 속성으로 폼에 사용한 필드를 지정한다.
success_url FormView, CreateView, UpdateView, DeleteView에서 사용하는 속성으로 폼에 대한 처리가 성공될 때 리다이렉트 되는 URL을 지정한다.

 

 

3-2. 메소드 오버라이딩

메소드명 설명
get_queryset() View, TemplateView, RedirectView, FormView 4개를 제외하고 모든 제네릭뷰에 사용하는 메소드. 출력 객체를 검사하기 위한 대상 QuerySet 객체 또는 출력 대상인 객체 리스트를 반환하는데 디플트는 queryset 속성값을 반환하고 해당 속성이 지정되지 않으면 ModelManager 클래스의 all() 메소드를 호출하여 QuerySet 객체를 생성하고 이를 반환한다.
get_context_data(**kwargs) TemplateView를 포함한 모든 제네릭 뷰에서 사용하는 메소드로 템플릿에서 사용할 컨텍스트 데이터를 반환한다.
form_valid(form) FormView, CreateView, UpdateView에서 사용하는 메소드로 get_success_url() 메소드가 반환하는 URL로 리다이렉트를 수행한다.

 

 

 

4. 제네릭 뷰 처리 흐름 파악

4-1. 필요성

클래스 상속 및 오버라이딩을 이용하여 응집도를 높인 제네릭 뷰의 특성상 내부의 메소드들을 조합할 때 처리 과정에 대한 이해가 있어야한다. 대표적으로 ListView와 Detailview를 통해 해당 제네릭 뷰 처리를 보면 다음과 같다.

 

 

4-2. ListView

  • 클라이언트의 HTTP 요청 중 GET 메소드에 따라서 get() 메소드가 실행된다.
  • 대상 테이블로부터 조건에 맞는 여러개의 객체를 가져온다.
  • 필요에 따라 객체에 추가 로직을 적용한다.
  • 결과를 출력하는 리스트를 object_list라는 컨텍스트 변수에 넣어 Template에 전달한다.
  • Template 파일에 따라 HTML의 응답 형태로 만든 후 최종적으로 클라이언트에 응답한다.
setup() → dispatch() → http_method_not_allowed() → get() → get_queryset() → get_context_data() → get_context_object_name() → render_to_response() → get_template_names()

 

 

4-3. DetailView

  • 클라이언트의 HTTP 요청 중 GET 메소드에 따라서 get() 메소드가 실행된다.
  • 대상 테이블로부터 조건에 맞는 한 객체를 가져온다.
  • 필요에 따라 객체에 추가 로직을 적용한다.
  • 결과를 출력하는 리스트를 object_list라는 컨텍스트 변수에 넣어 Template에 전달한다.
  • Template 파일에 따라 HTML의 응답 형태로 만든 후 최종적으로 클라이언트에 응답한다.
setup() → dispatch() → http_method_not_allowed() → get() → get_object() → get_queryset() → get_context_data() → get_context_object_name() → render_to_response() → get_template_names()

여기서 ListView와의 차이점이 있다면 다음과 같다.

ListView DetailView
대상 객체를 구하기 위해 get_queryset() 메소드를 이용한다. 대상 객체를 구하기 위해 get_object() 메소드를 이용한다.
- get_object() 메소드 내에 get_queryset() 메소드를 호출한다.

 

 

 

5. MRO(Method Resolution Order)

다중 상속이 가능한 파이썬의 특성상 장고의 제네릭 뷰에서도 해당 기능을 이용할 수 있다. 여기서 동일한 이름을 가진 메소드가 둘 이상의 부모 클래스에 존재할 경우(다이아몬드 문제) 어느 메소드를 먼저 사용해야 할지 결정하는 알고리즘이 필요한데 이러한 점을 해결하기 위해 나온 것이 MRO(메소드 결정 순서) 기능이다.

ListView의 상속 계층도

 

 

 

6. 제네릭 뷰의 페이징 처리

6-1. 정의

여러개의 객체들을 출력하는 ListView의 특성상 데이터가 수천, 수만 개가 될 경우 그만큼 불러와야 하는 서버의 부하가 커지는데 이를 해결하기 위한 것이 페이징으로 한 페이지마다 원하는 갯수만큼의 리스트를 출력하는 기능이다.

 

 

6-2. 페이징 기능 활성화

장고에서 페이징처리는 상대적으로 간편한데 단순히 View 계층에서 페이징 기능 클래스를 불러오고 원하는 속성 값을 입력하기만 하면 구현이 되기 때문이다. 여기서 템플릿 파일에 사용 되는 컨텍스트 변수는 다음과 같다.

  • object_list: 화면에 보여줄 객체의 리스트
  • is_paginated: 출력 결과가 페이징 처리되는지 여부를 알려주는 boolean 타입 변수
  • paginator: 장고에 지원하는 페이징 모듈(django.core.paginator.Paginator) 내 객체
  • page_obj: 장고에 지원하는 페이징 모듈(django.core.paginator.Page) 내 객체

 

 

6-3. Paginator 클래스

페이징의 메인 클래스로 객체 리스트와 페이지 당 항목 수를 인자로 받아 각 페이지 객체를 생성한다.

 

6-3-1. 인자

  • object_list: 페이징 대상이 되는 객체 리스트
  • per_page: 페이지당 최대 항목 수
  • orphans: 마지막 페이지에 넣을 수 있는 항목의 최소 개수
  • allow_empty_first_page: 첫 페이지가 비어 있어도 되는지 결정하는 boolean 타입 인자

 

6-3-2. 메소드

  • Paginator.page(number): Page 객체를 반환하는 메소드
  • Paginator.get_page(number): Page 객체를 반환하는 메소드. 인자가 숫자가 아닐 때 첫 페이지를 반환하고 음수이거나 최대 페이지 숫자보다 크면 마지막 페이지를 반환한다.

 

6-3-3. 속성

  • Paginator.count: 항목의 총 개수
  • Paginator.num_page: 페이지의 총 개수
  • Paginator.page_range: 1부터 시작하는 페이지 범위

 

 

6-4. Page 클래스

Paginator 객체에 의해 생성된 단위 페이지를 나타내는 객체

 

6-4-1. 인자

  • object_list: 페이징 대상이 되는 객체 리스트
  • number: 몇 번째 페이지인지 지정하는 페이지 인덱스
  • paginator: 페이지를 생성해주는 Paginator 객체

 

6-4-2. 메소드

  • Page.has_next(): 다음 페이지가 있을 때 True를 반환하는 메소드
  • Page.has_previous(): 이전 페이지가 있을 때 True를 반환하는 메소드
  • Page.has_other_pages(): 이전 혹은 다음 페이지가 있을 때 True를 반환하는 메소드
  • Page.next_page_number(): 다음 페이지 번호를 반환하는 메소드
  • Page.previous_page_number(): 이전 페이지 번호를 반환하는 메소드
  • Page.start_index(): 해당 페이지 첫 번째 항목의 인덱스를 반환하는 메소드로 1부터 카운트한다
  • Page.end_index(): 해당 페이지 마지막 항목의 인덱스를 반환하는 메소드로 1부터 카운트한다

 

6-4-3. 속성

  • Page.object_list: 현재 페이지 객체 리스트
  • Page.number: 현재 페이지 번호(1부터 시작)
  • Page.paginator: 현재 페이지를 생성한 Paginator 객체

 

 

 

7. 단축 함수

7-1. 정의

웹 개발시 자주 사용되는 기능들 중 템플릿 파일을 로딩한 후 컨텍스트 데이터를 적용하고 클라이언트로 응답하는 객체에 담아 반환하는 등의 과정들을 모아놓은 함수. 주로 함수형 뷰에서 사용한다.

 

 

7-2. render() 함수

템플릿 파일과 컨텍스트 사전을 인자로 받아 렌더링 후 HttpResponse 객체를 반환하는 함수

render(request, template_name, context=None, content_type=None, status=None, using=None)
# 단, request와 template_name을 제외한 나머지 인자들은 선택으로 적용 가능
  • request: 클라이언트로부터 보내온 요청 객체, 내부적으로 요청 객체에 담겨 있는 파라미터들을 이용해 RequestContext 객체를 만들고 이 데이터들을 컨텍스트 데이터에 추가한다.
  • template_name: 템플릿 파일명을 지정하는 인자로 여러 개일 경우 가장 먼저 찾는 파일을 사용한다.
  • context: 템플릿 컨텍스트 데이터가 담긴 파이썬 딕셔너리 객체.
  • content_type: 최종 결과에 사용되는 MINE 타입 인자. 디폴트는 DEFAULT_CONTENT_TYPE 설정 항목값을 따른다.
  • status: 응답에 포함될 상태 코드로 디폴트는 200이다.
  • using

 

 

7-3. redirect() 함수

to 인자로 주어진 URL로 이동하기 위한 HttpResponseRedirect 객체를 반환하는 함수.

redirect(to, *args, permanent=False, **kwargs)
  • to: 이동하기 위한 URL을 지정한다.
  • permanent: 응답 코드를 반환하는 인수로 True면 영구 리다이렉션(301)을 하고 False면 임시 리다이렉션(302 혹은 307)을 한다.

'Self-Study > DJango' 카테고리의 다른 글

장고의 템플릿 계층  (0) 2021.05.25
장고의 모델 계층  (0) 2021.05.24
장고의 MVT 패턴 개요  (0) 2021.05.21
장고 프레임워크의 개요  (0) 2021.05.21
Intro...  (0) 2021.05.15