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 |