ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Django] 함수형 뷰와 클래스형 뷰에 대한 정리
    django study 2020. 12. 20. 06:30

     

    장고의 클래스형 뷰(class-based view) = 제네릭뷰에 대한 내용을 간략히 다뤄보려한다.

    해당 내용에 대해서는 이미 여러 사이트들에도 언급되어있지만 공부도할겸해서 정리해보았다.

     

    <글쓰기 참고자료>

     

    파이썬 웹프로그래밍 실전편, 김석훈 지음, 한빛미디어

    https://ccbv.co.uk/

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

     

    <추가로 읽어보기>

    https://simpleisbetterthancomplex.com/article/2017/03/21/class-based-views-vs-function-based-views.html

    https://simpleisbetterthancomplex.com/series/2017/10/09/a-complete-beginners-guide-to-django-part-6.html#function-based-view

    https://yonghyunlee.gitlab.io/python/django-master-10/

    https://yuda.dev/245

     

     

    1. 장고의 제네릭 뷰 종류 (일부)

     

    분류 이름 기능
    Base View View 가장 기본이 되는 최상위 뷰
    TemplateView 템플릿이 주어지면 해당 탬플릿을 렌더링
    RedirectView URL이 주어지면 해당 URL로 리다이렉트
    Generic Display View ListView 조건에 맞는 여러개의 객체를 보여줌
    DetailView 객체하나에 대한 상세한 정보를 보여줌
    Generic Edit View FormView 폼이 주어지면 해당 폼을 보여줌
    CreateView 객체를 생성하는 폼을 보여줌
    UpdateView 기존객체를 수정하는 폼을 보여줌
    DeleteView 기존객체를 삭제하는 폼을 보여줌
    Generic Date View ArchiveIndexView 조건에 맞는 객체 및 객체들에 대한 날짜 정보를 보여줌.
    YearArchiveView  연도에 해당하는 객체들을 보여줌.
    이하 생략
     

     

     

    2. 자주 사용하는 속성과 메소드 정리

     

    제네릭뷰의 속성

    속성 설명 디폴트
    model 작업대상 데이터가 들어있는 모델을 지정, model대신 queryset으로 지정할수있음.  
    queryset 작업대상이 되는 QuerySet 객체를 지정  
    template_name 렌더링할 템플릿 파일명을 지정 <model_name>_list.html
    <model_name>_detail.html 외
    context_object_name 템플릿 파일에서 사용할 컨텍스트 변수명을 지정 object_list, object 외
    paginate_by 페이지기능이 활성화된 경우 페이지당 몇개항목을 출력할지 정수로 지정  
    date_field 날짜기반뷰에서 기준이 되는 필드를 지정, 이 필드를 기준으로 년/월/일을 검사  
    form_class 폼을 만드는데 사용할 클래스를 지정  
    initial 폼에 사용할 초기데이터를 사전{ }으로 지정  
    fields 폼에 사용할 필드를 지정  
    success_url 폼에 대한 처리가 성공한 후 리다이렉트할 url지정  

     

    제네릭뷰의 메소드

    메소드 설명
    get_queryset() 출력객체를 검색하기 위한 대상 QuerySet 객체 또는 출력대상인 객체리스트를 반환한다. 디폴트는 queryset속성값을 반환한다. queryset 속성이 지정되지 않는 경우는 모델 매니저 클래스의 all()메소드를 호출해 QuerySet 객체를 생성하고 이를 반환한다.
    get_context_data(**kwargs) 템플릿에서 사용한 컨텍스트 데이터를 반환
    form_valid(form) 제출된 폼이 유효성검사를 통과하면 호출되는 메소드
    또는 get_success_url()메소드가 반환하는 url로 리디이렉트를 수행

     

    속성 오버라이딩 

    속성 오버라이딩

     

    메소드 오버라이딩

    메소드 오버라이딩

     

    3. 예시

    아래는 함수형뷰와 클래스뷰의 (기능적으로 동일한) 여러가지 표현법이다.

    서로 비교를 해보면 위의 속성과 메소드를 이해하는데 도움이 된다.

     

    ListView의 예시

    def board_list(request):    
        boards = Board.objects.all()
        context = {'object_list': boards}    
        return render(request, 'board_list.html', context)
    
    def board_list(request): 
        if request.method == 'GET':
            boards = Board.objects.all()
            context = {'object_list': boards}   
        else: # POST
            # do something, return                
        return render(request, 'board_list.html', context)
    
    class BoardListView(View):
        def get(self, request):
            boards = Board.objects.all()
            context = {'object_list': boards}    
            return render(request, 'board_list.html', context)
        def post(self, request):
            # do something, return
    
    class BoardListView(TemplateView):    
        template_name = "board_list.html"
        def get_context_data(self, **kwargs):
            context = super().get_context_data(**kwargs)
            context['object_list'] = Board.objects.all()
            return context
    
    class BoardListView(ListView):
        model = Board
        context_object_name = 'object_list' # default: object_list
        template_name = 'board_list.html' # default: <modelname>_list.html
    
    class BoardListView(ListView):
        queryset = Board.object.order_by('pub_date')[:5] #only five
        #default: Board.object.all()
    
    class BoardListView(ListView):
        def get_queryset(self):
            return Board.object.order_by('pub_date')[:5] 
    

    DetailView의 예시

    def board_detail(request, pk):
        post = get_object_or_404(Board, pk=pk)
        context = {'object': post}    
        return render(request, 'board_detail.html', context)
    
    def board_detail(request, pk):
        try:
            board = Board.objects.get(pk=pk)
        except Book.DoesNotExist:
            raise Http404('board does not exist')    
        return render(request, 'board_detail.html', context={'object': board})
    
    class BoardDetailView(TemplateView):    
        template_name = "board_detail.html"
        def get_context_data(self, **kwargs):
            context = super().get_context_data(**kwargs)
            context['object'] = get_object_or_404(Board, pk=self.kwargs['pk'])  
            return context
    
    class BoardDetailView(DetailView):
        model = Board    
        context_object_name = 'object' # default: object
        template_name = 'board_detail.html' # default: <modelname>_detail.html

    FormView의 예시

    def new_post(request):
        if request.method == 'POST':
            form = PostForm(request.POST) # request에 담긴 데이터로 클래스폼을 생성
            if form.is_valid(): # 폼에 담긴 데이터가 유효한지 체크            
                # 폼데이터가 유효하면 데이터는 cleaned_data로 복사
                # 로직 처리 (예시) 
                # (1)
                # post = Post()
                # post.title = form.cleaned_data['title']
                # post.content = form.cleaned_data['content']
                # post.save()
                # (2)
                # post = form.save()
                return redirect('post_list') # 지정된 url로 리다이렉션
        else: # GET일 경우 빈 폼을 보여준다.
            form = PostForm()
        return render(request, 'new_post.html', {'form': form})
    
    
    class NewPostView(View):
        def post(self, request):
            form = PostForm(request.POST)
            if form.is_valid():
                # 로직 처리
                return redirect('post_list')
            return render(request, 'new_post.html', {'form': form})
    
        def get(self, request):
            form = PostForm()
            return render(request, 'new_post.html', {'form': form})
    
    
    class NewPostView(FormView):
        form_class = MyForm # 사용자에게 보여줄 폼을 정의한 forms.py 내의 클래스명
        template_name = 'new_post.html' # 폼을 포함하여 렌더링할 템플릿 파일명
        success_url = reverse('post_list') #처리가 정상적으로 완료되었을때 redirect할 url
    
        def form_valid(self, form):
            # 로직 처리
            return super(MyFormView, self).form_valid(form)

     

    다음번 포스트에는 FormView, Create/Update/Delete View에 대한 예시를 더 자세히 작성해 볼 예정이다.

     

    계속.

     

    'django study' 카테고리의 다른 글

    [Django] 장고에서 차트그리기  (0) 2020.12.19
    [Django] 장고 SQLite DB 사용관련 팁  (0) 2020.12.19
    [Django] 장고 기초 시작하기  (0) 2020.12.11

    댓글

Designed by Tistory.