장고 기본 CBV API

guava·2021년 12월 8일
0
post-custom-banner

파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트 강의를 듣고 정리한 글입니다.

장고의 뷰는 함수기반 뷰(FBV)와 클래스 기반 뷰(CBV)가 있다.

함수 기반 뷰

  • View 구현의 기본이며 이것을 알아야 응용이 가능하다.
  • 함수 기반 뷰의 공통기능은 장식자 문법으로 적용

클래스 기반 뷰

  • 짧은 코드로 많은 기능을 구현
  • 클래스 기반 뷰의 공통 기능들은 상속 문법으로 적용

장고에서는 Base View를 통해 기본적인 클래스 기반 뷰를 지원한다. 그리고 웹 개발시 반복적으로 개발해야할 요소를 줄여주는 Generic display views를 지원한다. 이는 Base View와 기타 다양한 믹스인을 상속받아 구현되었다.

API개발에 유용한 DRF(Django Rest Framework)도 CBV(Class Based View)의 철학을 따르기 때문에 CBV를 이해하는 것이 좋다.

Base View

TemplateView

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'),
]

RedirectView

View를 상속받는다. 리다이렉트 응답을 위한 뷰

방법1

# 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')
]

방법2

from django.views.generic import RedirectView


urlpatterns = [
    path('', RedirectView.as_view(pattern_name='instagram:post_list'), name='root'),
]

Generic display views

DetailView

1개 모델의 1개 Object에 대한 템플릿 처리를 위한 뷰
template_name이 지정되지 않았다면 모델명으로 템플릿 경로를 유추한다. (django/views/generic/detail.py)
{{ app_label }}/{{ model_name }}_detail.html

구현 예시 1 - DetailView를 상속 후 재정의

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())
]

구현 예시 2 - DetailView에 필요한 변수 삽입

from django.views.generic import DetailView

urlpatterns = [
    path('<int:pk>/', DetailView.as_view(model=Post))
]

ListView

1개 모델에 대한 List 템플릿 처리
페이징 처리를 지원한다.
template_name이 지정되지 않았다면 모델명으로 템플릿 경로를 유추한다. (django/views/generic/list.py)
{{ app_label }}/{{ model_name }}_list.html

구현 예시1 - ListView를 상속 후 재정의

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'),
]

구현 예시2 - ListView에 필요한 변수 삽입

모델 및 페이지네이션을 파라미터로 넘긴다.

from django.views.generic import ListView


post_list = ListView.as_view(model=Post, paginate_by=10)

urlpatterns = [
    path('', post_list, name='post_list'),
]
post-custom-banner

0개의 댓글