본문 바로가기

Development/Django

[django] class-based view와 function-based view?

학교 웹서버 컴퓨팅 수업에서 프로젝트를 진행하다가 

간단한 홈페이지를 만들고 싶어서 HomeView를 어떻게 구현할까 찾던 중에 

class-based view라는 것을 알게 되었습니다.

 

학교 수업 시간에 배운 View는 다음과 같았습니다.

@login_required(login_url="common:login")
def question_create(request):
    """
    pybo 질문등록
    """
    if request.method == "POST":
        form = QuestionForm(request.POST)
        if form.is_valid():
            question = form.save(commit=False)
            question.author = request.user  # 추가한 속성 author 적용
            question.create_date = timezone.now()
            question.save()
            return redirect("pybo:index")
    else:
        form = QuestionForm()
    context = {"form": form}
    return render(request, "pybo/question_form.html", context)

단순히 게시판에 새 질문을 등록하거나 조회하는 view입니다.

함수 안에서 request의 http method에 따라서 조건문으로 처리하는 방식입니다.

그런데 django 공식 문서에서 클래스로 처리하는 방식이 있었습니다.

Class-based views

Class-based views provide an alternative way to implement views as Python objects instead of functions. They do not replace function-based views, but have certain differences and advantages when compared to function-based views

 

정리해 보면 클래스형 view는 객체를 통해 view를 구현하는 방법입니다. 함수형 view에 비해서 여러 차이점과 장점들을 제공한다고 합니다.

 

because Django’s URL resolver expects to send the request and associated arguments to a callable function, not a class, class-based views have an as_view() class method which returns a function that can be called when a request arrives for a URL matching the associated pattern.

 

Django의 URL resolver는 호출 가능한 함수를 넘겨주어야 하기 때문에, as_view라는 클래스 메서드로 넘겨주어야 한다고 합니다. 그래서 요청에 따른 URL을 매칭하는 path 함수에서 두번째 인자로 다음과 같이 넘겨주어야 합니다.

# urls.py
from django.urls import path
from myapp.views import MyView

urlpatterns = [
    path("about/", MyView.as_view()),
]

 

클래스 view는 함수형 view와 달리, 하나의 함수에서 get, post, put,,, 등 메소드 별로 처리할 필요 없이

각 메서드별로 함수를 만들어서 처리가 가능하다는 점이 있습니다.

아래처럼 함수형 view는 하나의 함수 안에 다 구현해야 하지만,

from django.http import HttpResponse


def my_view(request):
    if request.method == "GET":
        # <view logic>
        return HttpResponse("result")

아래 클래스형 view는 하나의 클래스 안에 함수 별로 http method를 처리할 수 있게 됩니다.

from django.http import HttpResponse
from django.views import View


class MyView(View):
    def get(self, request):
        # <view logic>
        return HttpResponse("result")

django에선 목적에 따라 다양한 클래스 view를 제공하고 있습니다.

클래스 기반 제네릭 뷰(class-based generic view) 란 모델과 템플릿 레이어에서 특정 패턴을 반복해서 작성해야 하는 문제를 해결합니다.

view를 개발하면서 발견되는 일부 공통된 관용구와 패턴을 추상화하여 데이터의 일반적인 뷰를 빠르게 작성할 수 있도록 해줍니다.

클래스 기반 제네릭 뷰들의 대해선 자세한 내용은 django 공식 문서에서 확인하실 수 있습니다.

https://docs.djangoproject.com/en/1.10/ref/class-based-views/

 

Django

The web framework for perfectionists with deadlines.

docs.djangoproject.com

 

저는 단순히 홈페이지 설명만 보여주는 html 페이지를 구현할 것이라서 TemplateView 클래스를 상속받아 구현하였습니다.

TemplateView는 다음과 같은 경우에 가장 적합합니다.

  • 정적이며 거의 어떤 context도 필요로 하지 않는 단순한 텍스트를 표시하는 페이지를 구현하는 경우입니다.
  • GET 요청과 함께 작동하며 form이 없고, 어떠한 객체를 만들거나 수정할 필요 없는 페이지를 표시하는 경우입니다.

또한, TemapleView는 아래처럼 URL에서 포함된 context를 얻는 것에도 유용하다고 합니다.

from django.views.generic.base import TemplateView

from articles.models import Article


class HomePageView(TemplateView):
    template_name = "home.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["latest_articles"] = Article.objects.all()[:5]
        return context

 

제가 구현한 홈페이지에 사용할 HomeView 클래스입니다.

class HomeView(TemplateView):
    template_name = "common/home.html"

    def get(self, request):
        context = {
            "button_text": "저를 눌러주세요",
            "board_url": "/pybo",
        }
        return render(request, self.template_name, context)

    def post(self):
        return redirect(self.board_url)

home.html의 일부입니다.

<!-- First Container -->
<div class="container-fluid bg-1 text-center">
    <h3 class="margin" style="font-size: 80px">"Hello, Pybo!"</h3>
    <h3>Pybo 게시판으로 이동하기</h3>
    <a href="{{ board_url }}">{{ button_text }}</a>
</div>

 

 

참고 문헌

https://docs.djangoproject.com/en/4.2/topics/class-based-views/

 

Django

The web framework for perfectionists with deadlines.

docs.djangoproject.com

https://www.geeksforgeeks.org/templateview-class-based-generic-view-django/

 

TemplateView - Class Based Generic View Django - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

https://www.agiliq.com/blog/2017/12/when-and-how-use-django-templateview/

 

When and how to use Django TemplateView

When to use Template View? Django provides several class based generic views to accomplish common tasks. Simplest among them is TemplateView. TemplateView should be used when you want to present some information in a html page. TemplateView shouldn’t be

www.agiliq.com