본문 바로가기

코딩

django.views.generic 에 대하여

728x90
반응형

Django의 class-based views(CBV)의 핵심인 django.views.generic

 

기본 View 클래스들

 

TemplateView

from django.views.generic import TemplateView

class HomePageView(TemplateView):
    template_name = "home.html"
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['message'] = "Welcome!"
        return context

 

RedirectView

from django.views.generic import RedirectView

class GoogleRedirectView(RedirectView):
    url = "https://google.com"
    permanent = True  # 301 리다이렉트 사용​

 

 

 

Display Views (조회용)

 

DetailView

from django.views.generic import DetailView

class ArticleDetailView(DetailView):
    model = Article
    template_name = "article_detail.html"
    context_object_name = "article"
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['related_articles'] = Article.objects.filter(category=self.object.category)
        return context​
 
 
ListView
from django.views.generic import ListView

class ArticleListView(ListView):
    model = Article
    template_name = "article_list.html"
    context_object_name = "articles"
    paginate_by = 10
    
    def get_queryset(self):
        return Article.objects.filter(status='published').order_by('-created_at')

 

 

Editing Views (편집용)

 

CreateView

from django.views.generic import CreateView
from django.urls import reverse_lazy

class ArticleCreateView(CreateView):
    model = Article
    template_name = "article_form.html"
    fields = ['title', 'content', 'category']
    success_url = reverse_lazy('article-list')
    
    def form_valid(self, form):
        form.instance.author = self.request.user
        return super().form_valid(form)​
 
 
UpdateView
from django.views.generic import UpdateView

class ArticleUpdateView(UpdateView):
    model = Article
    template_name = "article_form.html"
    fields = ['title', 'content', 'category']
    
    def get_success_url(self):
        return reverse('article-detail', kwargs={'pk': self.object.pk})​
 
 
DeleteView
from django.views.generic import DeleteView

class ArticleDeleteView(DeleteView):
    model = Article
    template_name = "article_confirm_delete.html"
    success_url = reverse_lazy('article-list')

 

 

Mixin 클래스들

 

LoginRequiredMixin

from django.contrib.auth.mixins import LoginRequiredMixin

class PrivateArticleView(LoginRequiredMixin, DetailView):
    model = Article
    login_url = '/login/'
    redirect_field_name = 'next'​
 
PermissionRequiredMixin
from django.contrib.auth.mixins import PermissionRequiredMixin

class AdminArticleView(PermissionRequiredMixin, UpdateView):
    model = Article
    permission_required = 'articles.change_article'
    raise_exception = True
 

 

 

URL 설정 예시

from django.urls import path
from .views import (
    ArticleListView, 
    ArticleDetailView,
    ArticleCreateView,
    ArticleUpdateView,
    ArticleDeleteView
)

urlpatterns = [
    path('', ArticleListView.as_view(), name='article-list'),
    path('<int:pk>/', ArticleDetailView.as_view(), name='article-detail'),
    path('create/', ArticleCreateView.as_view(), name='article-create'),
    path('<int:pk>/update/', ArticleUpdateView.as_view(), name='article-update'),
    path('<int:pk>/delete/', ArticleDeleteView.as_view(), name='article-delete'),
]​

 

 

주요 메서드 오버라이딩

class CustomListView(ListView):
    def get_queryset(self):
        # 쿼리셋 커스터마이징
        return super().get_queryset().filter(status='active')
    
    def get_context_data(self, **kwargs):
        # 컨텍스트 데이터 추가
        context = super().get_context_data(**kwargs)
        context['extra_data'] = "Something extra"
        return context
        
    def get(self, request, *args, **kwargs):
        # GET 요청 처리 커스터마이징
        return super().get(request, *args, **kwargs)
        
    def post(self, request, *args, **kwargs):
        # POST 요청 처리 커스터마이징
        return super().post(request, *args, **kwargs)​
 
 
CBV의 장점
  • 코드 재사용성 향상
  • DRY(Don't Repeat Yourself) 원칙 준수
  • 상속을 통한 기능 확장 용이
  • 구조화된 코드 작성 가능
  • HTTP 메서드별 처리 로직 분리 용이
  • Mixin을 통한 기능 조합 가능

이러한 generic views를 사용하면 일반적인 CRUD 작업을 매우 빠르고 효율적으로 구현할 수 있으며, 필요한 경우 커스터마이징도 용이함. 특히 Mixin을 활용하면 인증, 권한 체크 등의 공통 기능을 쉽게 추가.

 


django.views.generic.View는 Django의 모든 클래스 기반 뷰(CBV)의 기본 클래스임.

 

기본 구조와 사용법

from django.views import View

class MyView(View):
    def get(self, request, *args, **kwargs):
        return HttpResponse("GET 요청 처리")
        
    def post(self, request, *args, **kwargs):
        return HttpResponse("POST 요청 처리")
        
    def put(self, request, *args, **kwargs):
        return HttpResponse("PUT 요청 처리")
        
    def delete(self, request, *args, **kwargs):
        return HttpResponse("DELETE 요청 처리")​
 
 
메서드 디스패치(Method Dispatch)
class CustomView(View):
    def dispatch(self, request, *args, **kwargs):
        # HTTP 메서드에 따른 처리 전에 실행
        print("요청 처리 시작")
        response = super().dispatch(request, *args, **kwargs)
        print("요청 처리 완료")
        return response​
 
 
HTTP 메서드별 처리 예시
from django.shortcuts import render
from django.http import JsonResponse

class ArticleView(View):
    template_name = 'article.html'
    
    def get(self, request):
        articles = Article.objects.all()
        return render(request, self.template_name, {'articles': articles})
    
    def post(self, request):
        data = json.loads(request.body)
        article = Article.objects.create(
            title=data['title'],
            content=data['content']
        )
        return JsonResponse({
            'id': article.id,
            'title': article.title
        })
    
    def put(self, request, article_id):
        data = json.loads(request.body)
        article = Article.objects.get(id=article_id)
        article.title = data.get('title', article.title)
        article.content = data.get('content', article.content)
        article.save()
        return JsonResponse({'status': 'success'})
    
    def delete(self, request, article_id):
        Article.objects.get(id=article_id).delete()
        return JsonResponse({'status': 'success'})​
 
 
as_view() 메서드 사용
# urls.py
from django.urls import path
from .views import ArticleView

urlpatterns = [
    path('articles/', ArticleView.as_view(), name='article-view'),
    path('articles/<int:article_id>/', ArticleView.as_view(), name='article-detail'),
]​
 
 
View 클래스의 주요 속성
class CustomView(View):
    http_method_names = ['get', 'post']  # 허용할 HTTP 메서드 지정
    content_type = 'text/html'  # 응답 컨텐츠 타입 설정
    
    def setup(self, request, *args, **kwargs):
        # 뷰 초기화 시 실행
        super().setup(request, *args, **kwargs)
        self.custom_setup()
    
    def custom_setup(self):
        # 커스텀 초기화 로직
        pass​
 
 
 
에러 처리
class ErrorHandlingView(View):
    def get(self, request):
        try:
            # 로직 처리
            result = self.process_something()
            return JsonResponse({'data': result})
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=400)
    
    def http_method_not_allowed(self, request, *args, **kwargs):
        # 허용되지 않은 HTTP 메서드 처리
        return JsonResponse(
            {'error': '이 메서드는 허용되지 않습니다'}, 
            status=405
        )​
 
 
미들웨어와 데코레이터 사용
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required
from django.views.decorators.csrf import csrf_exempt

@method_decorator(csrf_exempt, name='dispatch')
class ApiView(View):
    @method_decorator(login_required)
    def post(self, request):
        # 로그인된 사용자만 접근 가능
        return JsonResponse({'message': '성공'})​
 
 
실제 활용 예시
class DashboardView(View):
    template_name = 'dashboard.html'
    
    def get_context_data(self):
        return {
            'total_users': User.objects.count(),
            'active_users': User.objects.filter(is_active=True).count(),
            'recent_activities': Activity.objects.order_by('-created_at')[:10]
        }
    
    def get(self, request):
        context = self.get_context_data()
        return render(request, self.template_name, context)
        
    def post(self, request):
        if 'export' in request.POST:
            # 데이터 내보내기 로직
            return self.export_data()
        return self.get(request)
    
    def export_data(self):
        # 엑셀 파일 생성 등의 로직
        response = HttpResponse(content_type='application/ms-excel')
        response['Content-Disposition'] = 'attachment; filename="dashboard.xlsx"'
        return response​
 
 
View 클래스는 매우 유연하고 확장 가능한 구조를 제공하며, HTTP 메서드별로 로직을 명확하게 분리할 수 있음. 이를 통해 RESTful API나 복잡한 웹 애플리케이션을 구현할 때 코드를 체계적으로 구성.
 

 

728x90
반응형

'코딩' 카테고리의 다른 글

django 와 ckeditor  (1) 2025.01.06
부자 문자 부리기  (0) 2025.01.06
치매 예방: 화투 보다 코딩  (1) 2025.01.05
AI 시대에 코딩을 배워야 하는 이유  (2) 2025.01.05
늙어야 더 잘한다: 인공지능 코딩 부트캠프  (2) 2025.01.05