일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- django
- boj15683
- DynamicProgramming
- boj2239
- boj7579
- boj2252
- boj10775
- boj15998
- DP
- Spring
- BFS
- boj15654
- backtracking
- onTouch
- mysql
- bruteforce
- react
- DFS
- testdb
- boj15954
- euclideanalgorithm
- nestedjson
- 동적계획법
- springboot
- boj10942
- boj_15684
- boj_15685
- TDD
- BOJ
- onTouchListner
- Today
- Total
이마닷의 블로그
[django] 가장 기본적인 CBV(generic view) 본문
django는 기본적으로 MTV(Model, Template, View)의 기능으로 이루어진다. django 프로젝트에서 Model은 데이터를 저장하고 그에 맞는 필드와 메소드가 있는 클래스를 뜻하며, Template은 실제 보여질 페이지의 html 파일들을 뜻하는데 이때 css 개념도 포함된다. 마지막 View는 django 프로젝트를 통해 구현된 웹 페이지가 Model에 담겨진 데이터를 가지고 구현될 수 있도록 하는 함수들을 뜻한다.
FBV와 CBV는 각각 Function-Based View, Class-Based View를 뜻하는데, FBV는 말그대로 '함수', 즉 python에서 def 명령어를 통해 선언되는 단독의 함수들을 통해 구현된 View를 가리킨다. 이와 달리 CBV는 함수가 아닌 클래스, 그 중에서도 django에서 이미 구현되어 있는(django.views) generic view들을 import 하고, 이 클래스 내의 변수와 메소드를 조작하여 보다 손쉽게 구현할 수 있는 View를 뜻한다.
1. FBV의 기본적 구현법
def detail(request, question_id):
question = get_object_or_404(Question, pk = question_id)
ctx = {
'question': question,
}
return render(request, 'polls/detail.html', ctx)
위 코드는 가장 간단한 형태의 FBV이다. 원하는 데이터(question)를 가져오고, 각 템플릿에 띄워 보낼 정보(ctx)를 설정한 뒤, 이를 함수(render)를 사용해 서버에 보낼 수 있는 형태의 값으로 반환해주는 역할을 한다. 이때 반환되는 값은 urls.py에서 path 함수에 의해 url pattern들과 매핑된다. 데이터를 가져오는 필터가 되는 것은 pk뿐 아니라 모델 내의 다른 값이 될 수도 있다. 또한 ctx는 dict 형식으로 보내져야 하며, render 함수 이외에도 redirect, HttpResponse 계열 함수 등이 그 목적에 따라 달리 사용될 수 있다.
2. DetailView
from django.views import generic
class DetailView(generic.DetailView):
model = Question
template_name = 'polls/detail.html'
위 코드는 generic view들 중, DetailView에 관한 예시이다. DetailView는 단일한 데이터를 가져오고 싶을 때 사용하는 generic view 중 하나로, 웹서비스에서 어떤 데이터에 대한 상세 내용을 확인하고자 하는 웹 페이지를 구현할 때 주로 사용한다.
DetailView를 사용하기 위해서는, 위의 예시처럼 만들고자 하는 클래스(DetailView)에서 generic.DetailView를 상속받아 사용한다. model 변수에 가져오고자 하는 데이터의 모델 또는 클래스(Question) 명을 대입하고, 이와 연결시킬 html 파일명('polls/detail.html')을 template_name 변수에 대입한다. 별도의 DetailView 내부의 다른 변수값 지정이 없다면, 기본적으로 해당 model의 인스턴스 중 매핑된 url 패턴에 입력된 pk값을 가지는 인스턴스를 가져온다.(?)
3. ListView
from django.views import generic
class IndexView(generic.ListView):
model = Question
template_name = 'polls/index.html'
context_object_name = 'latest_question_list'
def get_queryset(self):
return Question.objects.order_by('-pub_date')[:5]
위 코드는 generic view들 중, ListView에 관한 예시이다. ListView는 여러 개의 데이터를 동시에 list 형태로 가져오고 싶을 때 사용하는 generic view 중 하나로, 웹서비스에서 존재하는 여러 데이터들의 목록을 확인하고, 이를 각 데이터 별 상세 페이지로 넘겨주는 역할을 하는 페이지를 구현할 때 주로 사용한다.
ListView를 사용하기 위해서는, 위의 예시처럼 만들고자 하는 클래스(IndexView)에서 generic.ListView를 상속받아 사용한다. DetailView와 마찬가지로, model과 template_name 변수에 가져오고자 하는 데이터의 모델(Question)과 html 파일명('polls/index.html')을 입력한다. context_object_name에 대해 문자열('latest_question_list')을 대입하는 것은 연결된 html 파일 내에서 사용하고자 하는 데이터의 변수 명을 새롭게 지정해주는 것이고, get_queryset 메소드의 재정의는 가져오고자 하는 데이터의 필터링 조건을 새롭게 지정(pub_date 기준으로 가장 나중의 5개 인스턴스 가져오기)해주기 위한 것이다.
4. url pattern과의 mapping
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('<int:pk>/', views.DetailView.as_view(),name='detail'),
]
위 코드는 django 프로젝트 내의 urls.py 파일로, url pattern을 각 view들과 매핑시켜주는 역할을 한다. 앞서 다루었던 두 generic View class를 참조하고, 그 중 as_view라는 메소드를 호출하여 FBV에서의 render 함수가 했던 역할을 수행하도록 한다. 웹 브라우저에서 기존 url에서 아무것도 붙지 않는 url에 접근한다면, IndexView.as_view()가 실행되어 연결된 html 파일이 브라우저에 띄워지고, '기존 url + 3/' 과 같은 형태의 url에 접근한다면, 3을 pk 값으로 가지는 Question 인스턴스에 대한 상세 html 파일이 브라우저에 띄워질 것이다.
'python' 카테고리의 다른 글
[django] 템플릿에서 context object의 메소드 사용하기 (0) | 2020.01.15 |
---|---|
[django] MySQL과 연동하기 (0) | 2019.09.29 |