파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트 강의를 듣고 정리한 글입니다.
장고의 뷰는 함수기반 뷰(FBV)와 클래스 기반 뷰(CBV)가 있다.
장고에서는 Base View를 통해 기본적인 클래스 기반 뷰를 지원한다. 그리고 웹 개발시 반복적으로 개발해야할 요소를 줄여주는 Generic display views를 지원한다. 이는 Base View와 기타 다양한 믹스인을 상속받아 구현되었다.
API개발에 유용한 DRF(Django Rest Framework)도 CBV(Class Based View)의 철학을 따르기 때문에 CBV를 이해하는 것이 좋다.
TemplateResponseMixin
, ContextMixin
, View
를 상속
템플릿 응답을 위한 뷰
# urls.py
from django.views.generic import TemplateView
# 방법1
class RootView(TemplateView):
template_name = 'root.html' # 템플릿 파일 지정 (추가로 content_type, response_class 등을 지정 가능)
urlpatterns = [
path('', RootView.as_view(), name='root'),
]
# 방법2
urlpatterns = [
path('', TemplateView.as_view(template_name='root.html'), name='root'),
]
View
를 상속받는다. 리다이렉트 응답을 위한 뷰
# urls.py
from django.views.generic import RedirectView
class TestRedirectView(RedirectView):
permanent = False # True: 301(영구적인 이동), False: 302(임시 이동)
url = None # URL 문자열
pattern_name = 'instagram:post_list' # URL Reverse를 수행할 문자열
query_string = False # QueryString을 그대로 넘길 것인지 여부
urlpatterns = [
path('', TestRedirectView.as_view(), name='root')
]
from django.views.generic import RedirectView
urlpatterns = [
path('', RedirectView.as_view(pattern_name='instagram:post_list'), name='root'),
]
1개 모델의 1개 Object에 대한 템플릿 처리를 위한 뷰
template_name이 지정되지 않았다면 모델명으로 템플릿 경로를 유추한다. (django/views/generic/detail.py)
→{{ app_label }}/{{ model_name }}_detail.html
from django.views.generic import DetailView
class PostDetailView(DetailView):
model = Post
queryset = Post.objects.filter(is_publish=True) # queryset의 조건필터를 입력해서 정의할 수 있다. (default: None)
slug_field = 'slug' # slug필드를 지정 (default: 'slug')
context_object_name = None # 컨텍스트에 정의할 키값 -> 템플릿 등에서 context[context_object_name]로 객체 접근 (default: None)
slug_url_kwarg = 'slug' # ?? (default: 'slug')
pk_url_kwarg = 'pk' # url 캡쳐 문자의 이름이 uid라면 이 변수도 'uid'로 정의한다. (default: 'pk')
# query_pk_and_slug = False
def get_queryset(self):
# 단순히 조건 필터가 아닌 로직이 삽입된 쿼리셋이 필요하다면, get_queryset()을 오버라이드 한다.
qs = super().get_queryset()
if not self.request.user.is_authenticated:
qs = qs.filter(is_publish=True)
return qs
def get_context_data(self, **kwargs):
# 컨텍스트 데이터를 수정할 때 오버라이드
# 컨텍스트에 object, model_name이라는 키값에 객체가 추가된다.
# 즉, context['object'], context['post']로 객체 접근이 가능
context = super().get_context_data(**kwargs)
# 추가로 필요한 데이터를 정의
context['test'] = '추가할 데이터'
return context
urlpatterns = [
path('<int:pk>/', PostDetailView.as_view())
]
from django.views.generic import DetailView
urlpatterns = [
path('<int:pk>/', DetailView.as_view(model=Post))
]
1개 모델에 대한 List 템플릿 처리
페이징 처리를 지원한다.
template_name이 지정되지 않았다면 모델명으로 템플릿 경로를 유추한다. (django/views/generic/list.py)
→{{ app_label }}/{{ model_name }}_list.html
from django.views.generic import ListView
class PostListView(ListView):
model = Post # 모델 지정
paginate_by = 10 # 페이지네이션 처리가 된다. (defulat: None)
allow_empty = True # 빈 쿼리셋 반환 가능 여부 설정 (default: True)
def get_queryset(self):
# 쿼리셋에 대한 로직을 삽입할 수 있다.
qs = super().get_queryset()
qs = qs.filter(...)
return qs
post_list = PostListView.as_view()
urlpatterns = [
path('', post_list, name='post_list'),
]
모델 및 페이지네이션을 파라미터로 넘긴다.
from django.views.generic import ListView
post_list = ListView.as_view(model=Post, paginate_by=10)
urlpatterns = [
path('', post_list, name='post_list'),
]