[django]dispatch()? generic view?

Hyeseong·2021년 1월 5일
0

class based view

목록 보기
2/2

dispatch()😀

dispatch() 메서드란?😙

class형 View는 URLconf에서 시이작!!

몇줄 정리

  • 클래스로 작성되어 있는 뷰 객체를 말한다.
  • 상속과 믹스인 기능 사용으로 코드의 재사용이 가능
  • 뷰의 체계적 관리
  • 제네릭 뷰 작성
from django.urls import path
from posting.views  import PostView, PostCommentView,PostLikeView

urlpatterns = [
    path('/create', PostView.as_view()),
    path('/read', PostView.as_view()),                              # 전체 포스트 조회기능
    path('/create/<int:pk>/comment', PostCommentView.as_view()),   # 댓글 생성
    path('/read/<int:pk>/comment', PostCommentView.as_view()),     # 댓글 조회
    
    path('/create/<int:pk>/like', PostLikeView.as_view()),           # 좋아요 등록
    path('/delete/<int:pk>/like', PostLikeView.as_view()),           # 좋아요 등록
    path('/read/<int:pk>/like', PostLikeView.as_view()),            # 좋아요 조회


]

URL패턴에서 어떻게 클래스 View로 넘어갈까요? 그건~!

  • as_view() 덕분입니다.
    • 클래스의 인스턴스 생성
    • 생성된 객체의 dispatch() 메서드를 호출.
      • dispatch()는 HTTP메서드 GET, POST중 어느것인지 파악해요.
    • 그럼 인스턴스에서 get, post 이름과 매칭되는 메서드로 연결되요
    • 해당 메서드가 정의되지 않았다?! 그럼 HttpResponseNotAllowed Error 발생!

View 클래스 정의!

class PostView(View):
    def post(self, request):
        try:
            data       = json.loads(request.body)
            user       = User.objects.get(email=data['email'])
            title      = data['title']
            content    = data['content']
            image_url  = data['image_url']

            p = re.compile('^([12]\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01]))$')

            if not title and content and image_url:
                return JsonResponse({'MESSAGE': "YOUR REQUEST IS NOT ADEQUATE!"},status=400)
            
            if not Post.objects.filter(title=title).exists():
                Post.objects.create(
                                    user      = user, # 객체로 지정해야함 다른 속성값으로 하면 오류 발생함!
                                    title     = title,
                                    content   = content,
                                    image_url = image_url,
                                    )
                return JsonResponse({'MESSAGE': 'POST REQUEST SUCCEEDED!'}, status=200)
            return JsonResponse({'MESSAGE': 'TITLE ALREADY EXISTS!'}, status=400)

        except KeyError:
            return JsonResponse({'MESSAGE': 'KEY ERROR OCCURED!'},status=400)

        except ValueError:
            return JsonResponse({'MESSAGE': 'VALUE ERROR OCCURED!'},status=400)
        
        except User.DoesNotExist:
            return JsonResponse({'MESSAGE':'USER DOES NOT EXISTS!'},status=400)

        except Post.DoesNotExist:
            return JsonResponse({'MESSAGE':'POST DOES NOT EXISTS!'},status=400)
       
    def get(self, request):
        try:
            posts  = Post.objects.all()
            post_list = []

            for i in posts:
                post_list.append(
                     {
                        'posts.id'        :i.id,
                        'posts.user'      :i.user.email,
                        'posts.title'     :i.title,
                        'posts.content'   :i.content,
                        'posts.created'   :i.created_dt,
                        'posts.image_url' :i.image_url,
                    }
                )
            return JsonResponse({'RESULT':post_list }, status=200)
        
        except KeyError:
            return JsonResponse({'MESSAGE': 'KEY ERROR OCCURED!'},status=400)

        except ValueError:
            return JsonResponse({'MESSAGE': 'VALUE ERROR OCCURED!'},status=400)

        except Post.DoesNotExist:
            return JsonResponse({'MESSAGE':'POST DOES NOT EXISTS!'},status=400)
  • MyView 클래스는 View 클래스를 상속 받음

  • View 클래스에는 as_view() 메서드와 dispatch()메소드가 정의되어 있음.

    CBV의 GOOD POINTS~!😂

    하나! GET, POST 등의 HTTP 메소드에 따른 처리를 메소드명으롤 구분 할 수 있어, 좀 더 깔끔한 구조의(IF 문이 없는)코드를 생산할 수 있다.
    둘! 다중상속이 가능하여 코드 재사용성과 개발 생산성 UP!

HTTP HEAD 메소드를 코딩한 예시

from django.http import HttpResponse  
from django.views.generic import ListView  
from books.models import Book

class BookListView(ListView):  
    model = Book

    def head(self, *args, **kwargs):
        last_book = self.get_queryset().latest('publication_date')
        response = HttpResponse('')
        response['Last-Modified'] = last_book.publication_date.strftime('%a, %d %b %y %H:%M:%S GMT')
        return response

위 예제는 서점에 방문한 직후에 새롭게 출간된 책이 있는지를 문의하는 로직이다. 최근 발간된 책이 없는데도 책 리스트를 서버로부터 받아 오게되면 네트워크 대역폭이 낭비되므로, 이를 방지하기 위해 HEAD 메소드를 사용한다. HEAD 요청에 대한 응답은 바디 없이 헤더만 보내주면 된다.

상속기능~😎

대부분의 클래스형 뷰는 장고가 주는 GENERIC VIEW를 상속 받아서 작성해요.

Generic View란?
공통적으로 사용하는 기능들을 추상화하여 장고에서 기본 제공형태로 만들어진 클래스형뷰.

Django Generic View 종류~!😉

Django 의 제네릭 뷰

Django 에서 제공하는 제네릭 뷰는 다음과 같이 4가지로 분류할 수 있다.

  • Base View: 뷰 클래스를 생성하고, 다른 제네릭 뷰의 부모 클래스를 제공하는 기본 제네릭 뷰
  • Generic Display View: 객체의 리스트를 보여주거나, 특정 객체의 상세 정보를 보여준다.
  • Generic Edit View: 폼을 통해 객체를 생성, 수정, 삭제하는 기능을 제공한다.
  • Generic Date View: 날짜 기반 객체의 년/월/일 페이지로 구분해서 보여준다.

아래는 위 4가지 분류에 따른 구체 뷰 클래스에 대한 설명을 보여준다.

  • Base View
    • View: 가장 기본이 되는 최상위 제네릭 뷰
    • TemplateView: 템플릿이 주어지면 해당 템플릿을 렌더링한다.
    • RedirectView: URL이 주어지면 해당 URL로 리다이렉트 시켜준다.
  • Generic Display View
    • DetailView: 객체 하나에 대한 상세한 정보를 보여준다.
    • ListView: 조건에 맞는 여러 개의 객체를 보여준다.
  • Generic Edit View
    • FormView: 폼이 주어지면 해당 폼을 보여준다.
    • CreateView: 객체를 생성하는 폼을 보여준다.
    • UpdateView: 기존 객체를 수정하는 폼을 보여준다.
    • DeleteView: 기존 객체를 삭제하는 폼을 보여준다.
  • Generic Date View
    • YearArchiveView: 년도가 주어지면 그 년도에 해당하는 객체를 보여준다.
    • MonthArchiveView: 월이 주어지면 그 월에 해당하는 객체를 보여준다.
    • DayArchiveView: 날짜가 주어지면 그 날짜에 해당하는 객체를 보여준다.

제네릭뷰 공식 문서

profile
어제보다 오늘 그리고 오늘 보다 내일...

0개의 댓글