본 글은 Holix의 "리액트와 함께 장고 시작하기 Complete" 강의를 듣고 작성한 일지입니다.
Class Based View
CBV는 View 함수를 만들어주는 클래스를 의미합니다. as_view() 클래스 함수를 통해 View 함수를 생성하고, 상속을 통해 여러 기능들을 믹스인합니다.
그 전에 앞서 post_detail 뷰 함수를 구현하는데, pk를 전달할 때 해당하는 id가 없으면 DoesNotExist 예외 처리가 발생합니다. 이때 try, except 구문을 사용할 수도 있지만 그보다 더 편리한 것은 get_object_or_404 를 사용하는 것입니다.
# views.py
from django.http.response import Http404, HttpResponse, Http404
def post_detail(request: HttpRequest, pk: int) -> HttpResponse:
try:
post = Post.objects.get(pk=pk)
except Post.DoesNotExist:
raise Http404
# views.py
from django.shortcuts import get_object_or_404, render
def post_detail(request: HttpRequest, pk: int) -> HttpResponse:
post = get_object_or_404(Post, pk=pk)
장고에서 기본으로 제공하는 CBV를 활용하는 예시는 아래와 같습니다.
# views.py
from django.views.generic import DetailView
# pk_url_kwarg를 'pk'로 지정했으면 따로 명시해주지 않아도 됨
post_detail = DetailView.as_view(model=Post, pk_url_kwarg='id')
article_detail = DetailView.as_view(model=Article, pk_url_kwarg='id')
# 상속을 통한 CBV 속성 정의
from django.views.generic import DetailView
class PostDetailView(DetailView):
model = Post
pk_url_kwarg = 'id'
post_detail = PostDetailView.as_view()
위 코드 주석에서 언급한 pk_url_kwarg 는 urls.py 에서 path에 넘겨주는 쿼리 파라미터를 가리킵니다.
# urls.py
urlpatterns = [
path('post/<int:id>/', post_detail), # 'pk'라면 위 코드에서 pk_url_kwarg 파라미터 불필요
path('article/<int:id>/', article_detail),
]
장고의 CBV는 강력한 기능이 될 수 있지만, FBV(함수 기반 뷰)에 대한 이해 없이 사용한다면 위험해질 수 있다고 합니다. 항상 공식문서 및 소스코드를 살펴보는 연습이 필요할 것 같습니다.
https://github.com/django/django/tree/main/django/views/generic
Base Views
View는 모든 CBV의 모체이지만 해당 CBV를 직접 쓸 일은 거의 없습니다. http method별로 지정 이름의 멤버함수를 호출토록 구현해 놓았는데, 예를 들어 GET 요청이 들어오면 소문자 get 함수를 호출하는 것입니다.
일단 TemplateView 를 한 번 시도해보겠습니다.
깃허브에 있는 소스코드를 보는 것도 좋지만 속성과 메서드가 잘 정리된 사이트도 첨부합니다.
https://ccbv.co.uk/projects/Django/3.1/django.views.generic.base/TemplateView/
# 프로젝트/urls.py
from django.views.generic import TemplateView
urlpatterns = [
path('', TemplateView.as_view(template_name='root.html'), name='root'),
...,
]
# settings.py
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
# File System Template Loader <- 특정 앱에 속하지 않은 탬플릿용
os.path.join(BASE_DIR, 'instagram', 'templates'),
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
...
],
},
},
]
위와 같이 설정하면 instagram이란 폴더 내부에 templates란 폴더를 생성하시면 됩니다. 물론 상위 폴더를 정하지 않아도 되며 그럴 경우 templates란 폴더는 프로젝트 디렉토리에 생성하시면 됩니다. 그러면 루트 url에 접속하더라도 root.html 을 작성해줬기 때문에 해당 html 내용을 화면에 보여줄 것입니다.
다음은 RedirectView를 살펴보겠습니다.
https://ccbv.co.uk/projects/Django/3.1/django.views.generic.base/RedirectView/
# 프로젝트/urls.py
from django.views.generic import TemplateView, RedirectView
urlpatterns = [
path('', RedirectView.as_view(url='/blog1/'), name='root'),
...,
]
말 그대로 특정 url에 접속했을 때 해당 url이 없어졌거나 임시로 멈춘 경우 다른 url로 이동하게끔 만들어주는 것입니다. 영구적 이동 대신 임시로 이동하는 것을 하고(permanent=False <- 디폴트), 이동할 url은 blog1으로 지정했습니다.
이렇게 하면 "127.0.0.1:8000/"에 접속해도 바로 "127.0.0.1:8000/blog1/" 주소의 페이지로 이동하게 됩니다. 직접 url을 명시하지 않고 URL Reverse를 통한 방법도 있습니다. 이를 위해선 지난 시간에 설명드렸듯이 앱의 urls.py 에서 app_name 변수를 지정해야 합니다.
# 앱/urls.py
app_name = 'blog1'
# 프로젝트/urls.py
from django.views.generic import TemplateView, RedirectView
urlpatterns = [
path('', RedirectView.as_view(pattern_name='blog1:post_list'), name='root'),
...,
]
참고로 장고에서는 url을 직접 명시하는 것보단 pattern_name을 선호한다고 합니다.
'문돌이 존버 > Django 스터디' 카테고리의 다른 글
장고(Django), 뷰 장식자(View decorator) 및 Generic Date Views (0) | 2021.09.20 |
---|---|
장고(Django), CBV API Generic display views (0) | 2021.09.19 |
장고(Django), URL Dispatcher와 정규표현식 (0) | 2021.09.18 |
장고(Django), 다양한 응답의 함수 기반 뷰(2) (0) | 2021.09.18 |
장고(Django), 다양한 응답의 함수 기반 뷰(1) (0) | 2021.09.12 |