뷰는 요청을 받아서 응답을 반환해주는 호출 가능한 객체이다. 장고에서는 뷰를 함수로도 작성할 수 있고 클래스로 작성가능 하다.
클래스형 뷰 (Class-based View)를 사용하면 상속과 믹스인 기능을 사용해서 코드를 재사용할 수 있고, 뷰를 체계적으로 구성할
수도 있다.
간단한 경우에는 함수형 뷰로 신속하게 개발하는 것도 하나의 방법이지만, 로직이 복잡해지고 프로젝트가 커질수록 클래스형 뷰의
장점이 효과를 발휘할 것이다.
1. 클래스형 뷰의 시작점
클래스형 뷰를 사용하기 위해서는 가장 먼저 URLconf에서 함수형 뷰가 아니라 클래스형 뷰를 사용한다는 점을 표시해줘야 한다.
예를 들어, MyView라는 클래스형 뷰를 사용한다면 URLconf는 다음과 같은 모습
장고의 URL 해석기는 요청과 관련된 파라미터들을 클래스가 아니라 함수에 전달하기 때문에, 클래스형 뷰는 클래스로 진입하기
위한 as_view() 클래스 메소드를 제공한다. 이 메소드를 진입 메소드라고 부르기도 한다.
as_view() 진입 메소드의 역할은 클래스의 인스턴스를 생성하고, 그 인스턴스의 dispatch() 메소드를 호출한다.
dispatch() 메소드는 요청을 검사해서 GET, POST 등의 어떤 HTTP 메소드로 요청되었는지를 알아낸 다음, 인스턴스 내에서 해당
이름을 갖는 메소드로 요청을 중계해준다. 만일 해당 메소드가 정의되어 있지 않으면 HttpResponseNotAllowed 익셉션을 발생
시킨다.
MyView 클래스는 views.py 파일에 코딩하면 된다.
as_view()라는 메소드는 장고에서 기본적으로 제공해주므로, 개발자가 별도로 정의하지 않아도 된다. 위에서 언급한 dispatch()
메소드 역시 명시적으로 정의해주지 않더라도 장고에서 기본적으로 제공해준다. 그래서 MyView 클래스에는 이 메소드들을
정의하지 않아도 사용할 수 있는 것. 이런 상속 기능은 클래스형 뷰의 장점 중의 하나이다.
2. 클래스형 뷰의 장점 - 효율적인 메소드 구분
함수형 뷰와 비교할 때 자주 이야기되는 클래스형 뷰의 장점 2가지
- GET, POST 등의 HTTP 메소드에 따른 처리 기능을 코딩할 때, IF 함수를 사용하지 않고 메소드명으로 구분할 수 있으므로 코드의
구조가 깔끔해진다.
- 다중 상속과 같은 객체 지향 기술이 가능하므로, 클래스형 제네릭 뷰 및 믹스인 클래스 등을 사용할 수 있고, 이는 코드의 재사용성
이나 개발 생산성을 획기적으로 높여준다.
함수형 뷰에서 GET 메소드를 처리하는 로직을 작성한다면
요청 request 객체의 method 속성을 체크하는 로직이 필요하므로, 항상 if 조건의 체크 문장이 필요하다.
반면, 클래스형 뷰로 작성한다면
클래스형 뷰에서는 HTTP 메소드 이름으로 클래스 내에 메소드를 정의하면 된다. 단 메소드명은 소문자로 해야 하므로 get(),
post(), head() 등과 같이 이름을 지어주면 된다. 클래스형 뷰에는 내부적으로 dispatch() 메소드가 있기 때문에 dispatch()
메소드가 GET, POST 등의 어떤 HTTP 메소드로 요청되었는지를 알아낸 다음 해당 이름을 갖는 메소드로 요청을 중계해준다.
또 다른 예로, GET, POST 이외의 다른 HTTP 메소드인 HEAD 메소드로 코딩하는 예를 보면 HEAD HTTP 메소드는 서점에 방문한
직후에 새롭게 출간된 책이 있는지 서버에게 문의하는 용도이ㅏㄷ. 최근 발간된 책이 없는데도 책 리스트를 서버로부터 받아온다면,
네트워크 대역폭이 낭비되므로 이를 방지하기 위해 HEAD 메소드를 사용한 것이다. HTTP 프로토콜 규격에 따르면 HEAD 요청에
대한 응답은 바디 없이 헤더만 보내주면 된다.
HEAD 요청을 처리하는 뷰 로직은 간단하게 클래스 내에 head() 메소드를 정의하면 된다.
3. 클래스형 뷰의 장점 - 상속 기능 가능
작성하는 클래스형 뷰의 대부분은 장고가 제공해주는 제네릭 뷰를 상속받아 작성한다.
웹 애플리케이션을 개발하는 경우, 공통적으로 반복되는과정들이 많이 발생한다. 장고에서는 특히 모델, 뷰, 템플릿 개발 과정에서
이러한 단순 반복 작업을 많이 없애주는데, 제네릭 뷰가 바로 뷰 개발 과정에서 개발자의 단순 반복 작업을 덜어주는 기능이다.
제네릭 뷰란, 뷰 개발 과정에서 공통적으로 사용할 수 있는 기능들을 추상화하고, 이를 장고에서 미리 만들어 기본적으로 제공하는
클래스형 뷰를 말한다.
로직에 따라 클래스형 뷰를 작성할 때는 제네릭 뷰를 상속받아서 작성하는 것이 대부분이다. 뷰가 클래스이기 때문에 상속 기능이
가능하고 우리가 작성한 클래스형 뷰를 상속받아서 또 다른 클래스형 뷰를 작성할 수 있으므로 확장성도 증가한다.
/about/이라는 URL로 웹 요청이 들어오면, about.html 템플릿을 보여준다는 코딩
urls.py 파일에서는 클래스형 뷰의 as_view() 메소드를 호출하도록 하였다. views.py 파일의 소스를 보면, 단 2줄로 로직을 완성
이것이 가능한 이유는 장고가 제공해주는 TemplateView라는 제네릭 뷰를 상속받아 사용하고 있기 때문이다. 요청 request
객체를 분석하고, 템플릿 시스템에 넘겨줄 컨텍스트 변수를 구성하는 것은 모두 TemplateView 제네릭 뷰에서 처리한다.
조금 다른 방식으로 TemplateView 제네릭 뷰를 사용할 수도 있다. urls.py 파일에서 about.html 템플릿 파일을 지정해주면
views.py 파일에 클래스형 뷰를 작성하는 것도 불필요해진다.
TemplateView는 뷰에 특별한 로직이 없고, URL에 맞춰 해당 템플릿 파일의 내용만 보여줄 때 사용하는 제네릭 뷰이다.
오버라이딩 기능
이런 클래스 속성을 필요에 따라 오버라이딩하여 사용할 수도 있다. 하위 클래스인 AboutView 클래스에서 오버라이딩할 수도 있고
as_view() 메소드를 통해서도 오버라이딩할 수 있다. 상속과 그에 따른 오버라이딩 기능은 클래스형 뷰를 이해하는 데 필수적인
개념이면서도 자주 사용된다.
4. 클래스형 제네릭 뷰
장고에서는 URL 패턴으로부터 파라미터를 추출하고 그 파라미터로 데이터베이스를 검색하여 해당 데이터를 템플릿 시스템에서
렌더링하는 기능처럼, 웹 프로그램 개발 시 공통적으로 사용할 수 있는 로직을 이미 개발해 놓고 기본 클래스로 제공하고 있기
때문에 이를 상속받아 사용하면 된다.
장고에서는 이렇게 공통된 로직을 미리 개발해 놓고 제공하는 뷰를 제네릭 뷰(generic view)라고 부른다.
제네릭 뷰는 클래스형 뷰로 구성되어 있다. -> 자유자재로 사용할 수 있어야 한다.
장고에서 제공하는 제네릭 뷰의 4가지 분류
- Base View : 뷰 클래스를 생성하고, 다른 제네릭 뷰의 부모 클래스를 제공하는 기본 제네릭 뷰이다.
- Generic Display View : 객체의 리스트를 보여주거나, 특정 객체의 상세 정보를 보여준다.
- Generic Edit View : 폼을 통해 객체를 생성, 수정, 삭제하는 기능을 제공한다.
- Generic Date View : 날짜 기반 객체의 연/월/일 페이지로 구분해서 보여준다.
5. 클래스형 뷰에서 폼 처리
폼 처리 과정 3가지 경우
- 최초의 GET : 사용자에게 처음으로 폼(빈 폼 또는 초기 데이터로 채워진 폼)을 보여줌
- 유효한 데이터를 가진 POST : 데이터를 처리함, 주로 리다이렉트 처리됨
- 유효하지 않은 데이터를 가진 POST : 보통은 에러 메시지와 함게 폼이 다시 출력됨
IF 문장으로 HTTP의 GET 방식과 POST 방식을 구분하여 뷰가 GET 방식으로 요청을 받은 경우에는 사용자에게 처음 폼을
보여주도록하고 처리하고, 뷰가 POST 방식으로 요청을 받은 경우에는 데이터가 담긴 제출된 폼으로 간주하여 처리하는 방식
-> 클래스형 뷰로 코딩
클래스형 뷰에서는 HTTP의 GET 방식과 POST 방식을 클래스 내의 메소드로 구분하여 처리함으로써, 코드 구조가 깔끔해지고
읽기도 편해진다.
폼 처리용 제네릭 뷰 FormView 상속받아 처리
FormView 제네릭 뷰를 사용하면 FormView 클래스에 이미 정의되어 있기 때문에 클래스 내에 get(), post() 메소드 정의 불필요
유의사항 4가지
- form_class : 사용자에 보여줄 폼을 정의한 forms.py 파일 내의 클래스명 - MyForm
- template_name : 폼을 포함하여 렌더링할 템플릿 파일 이름 - form_template.html
- success_url : MyFormView 처리가 정상적으로 완료되었을 때 리다이렉트시킬 URL - /thanks/
- form_valid() 함수 : 유효한 폼 데이터로 처리할 로직 코딩, super() 함수를 사용하면, success_url로 지정된 URL로 리다이렉션
'Django' 카테고리의 다른 글
[Django] 로그 남기기 (0) | 2022.01.21 |
---|---|
[Django] 폼 처리하기 (0) | 2022.01.07 |
[Django] 템플릿 코드 (0) | 2022.01.05 |
[Django] Django 프로젝트의 settigns.py 설정하기 (0) | 2022.01.03 |
[Django] Django 프로젝트의 settigns.py 설정하기 (0) | 2022.01.03 |