반응형
지금까지 Django 학습한 내용을 바탕으로 정리를 해보려 한다.
목차 |
1. CBV (Class Based View)
2. Django Generic Views
3. request(요청) 처리
4. response(응답) 관련 함수
[작업 환경]
MacOS, PyCharm
pyenv, poetry
Python, Django
1. CBV (Class Based View) |
1. CBV란?
- Django에서 뷰를 클래스(Class)로 작성하는 방식이다.
- FBV에 비해 구조적이고 재사용성이 좋다.
- 요청 방식에 따라 def get(), def post() 와 같이 함수(클래스 메소드) 형태로 정의할 수 있다.
📌 '그래서 FBV보다 CBV가 무조건 좋다.' 이런 의미가 아니라,
프로젝트 규모와 요구사항에 따라 적합한 방식을 선택하여 사용하면 된다.
⭐️ FBV vs. CBV 비교
구분 | FBV | CBV |
개념 | 뷰 로직을 함수로 작성 | 뷰 로직을 클래스로 작성 |
코드 구조 | 직관적이며 간단 | 구조적이고 재사용성이 높음 |
Django 요청 메소드 처리 |
if request.method == 'GET': pass elif request.method == 'POST': pass 의 구조로 작성 (수동처리) |
def get(), def post() 등 클래스 메소드 형태로 작성 가능 상속 받은 부모 클래스에 따라 Django 메소드 자동 인식 됨 |
코드 재사용 | 중복가능성 있음 | 믹스인(Mixin), 상속 등올 재사용 쉬움 |
코드 커스터마이징 | 자유도가 높음 | Django 기본 메소드 오버라이딩 방식 😱 기본 속성, 메소드를 어느정도 알아야 함 |
테스트 용이성 | 상대적으로 용이 | 구조가 복잡할 수 있음 |
🧐 FBV 정리글 : https://jjincoding-helloworld.tistory.com/139
📌 사용예시)
from django.contrib.auth.mixins import LoginRequiredMixin
from django.db.models import Q
from django.http import HttpResponseRedirect, Http404
from django.shortcuts import get_object_or_404
from django.urls import reverse_lazy
from django.views.generic import ListView, CreateView, UpdateView, DeleteView
from blog.forms import CommentForm, BlogPostForm
from blog.models import Blog, Comment
# FBV-blog_list(request)와 동일
class BlogListView(ListView):
queryset = Blog.objects.all()
ordering = ('-created_at',)
template_name = 'blog_list.html'
paginate_by = 10
def get_queryset(self):
queryset = super().get_queryset()
q = self.request.GET.get('q')
if q:
queryset = queryset.filter(
Q(title__icontains=q) |
Q(content__icontains=q)
)
return queryset
# FBV-blog_detail와 동일
class BlogDetailView(ListView):
model = Comment
template_name = 'blog_detail.html'
paginate_by = 10
def get(self, request, *args, **kwargs):
self.object = get_object_or_404(Blog, pk=kwargs.get('pk'))
return super().get(request, *args, **kwargs)
def get_queryset(self):
return self.model.objects.filter(blog=self.object).prefetch_related('author')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['comment_form'] = CommentForm()
context['blog'] = self.object
return context
# FBV-blog_create와 동일
# LogiRequiredMixin = @login_required()
class BlogCreateView(LoginRequiredMixin, CreateView):
model = Blog
template_name = 'blog_form.html'
form_class = BlogPostForm
def form_valid(self, form):
self.object = form.save(commit=False)
self.object.author = self.request.user
self.object.save()
return HttpResponseRedirect(self.get_success_url())
def get_success_url(self):
return reverse_lazy('blog:detail', kwargs={'pk':self.object.pk})
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['sub_title'] = '작성'
context['btn_name'] = '생성'
return context
# FBV-blog_update와 동일
class BlogUpdateView(LoginRequiredMixin, UpdateView):
model = Blog
template_name = 'blog_form.html'
form_class = BlogPostForm
def get_queryset(self):
queryset = super().get_queryset()
if self.request.user.is_superuser: # if 혹은 if not 사용으로 분리해주면 됨
return queryset # superuser면 전체 쿼리 반환
return queryset.filter(author=self.request.user) # superuser 아니면 해당 user 정보의 쿼리만 출력
def form_valid(self, form):
print(form.cleaned_data) # cleaned_data : 출력값을 정리해서 보여줌
return super().form_valid(form)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['sub_title'] = '수정'
context['btn_name'] = '수정'
return context
# FBV-blog_delete와 동일
class BlogDeleteView(LoginRequiredMixin, DeleteView):
model = Blog
def get_queryset(self):
queryset = super().get_queryset()
if not self.request.user.is_superuser: # if 혹은 if not 사용으로 분리해주면 됨
return queryset.filter(author=self.request.user)
return queryset
def get_success_url(self):
return reverse_lazy('blog:list')
2. Django Generic Views |
😆 Django Generic Views 클래스 정리
클래스 | 기능 | 사용 목적 |
CreateView | 객체 생성 + 저장 | 게시글 작성, 회원가입 등 |
UpdateView | 객체 수정 | 게시글 수정, 댓글 수정 등 |
ListView | 객체 목록 조회 | 게시글 목록, 댓글 목록 등 |
DetailView | 객체 상세 조회 | 게시글 상세, 사용자 정보 보기 등 |
DeleteView | 객체 삭제 | 게시글 삭제, 댓글 삭제 등 |
TemplateView | 템플릿만 보여줌 | 공지사항, 소개 페이지 등 |
FormView | 커스텀 폼 처리 | 문의 폼, 피드백 등 |
⭐️ CBV에서 자주 사용되는 속성과 메소드 정리
구분 | 이름 | 설명 |
속성 | model | 연동할 모델 지정 |
form_class | 사용할 폼 클래스 지정 | |
template_name | 사용할 템플릿 경로 지정 | |
queryset | 조회할 기본 쿼리셋 지정 get_queryset()을 통해 동적으로 처리 가능 |
|
success_url | 작업 완료 후 리디렉션할 URL get_success_url, get_absoulte_url() 대체 가능 reverse_lazy()와 함께 자주 사용됨 |
|
context_object_name | 템플릿에서 사용할 객체 이름 변경 기본이 'object_list, object' 임 |
|
paginate_by | 페이지당 항목 수 지정 주로 ListView에서 사용 |
|
메소드 | get_queryset() | 쿼리셋을 동적으로 정의 필터링, 정렬 등에 활용 |
get_object() | 조회할 단일 객체를 커스터마이징할 때 사용 | |
get_form_class() | 사용할 폼 클래스를 동적으로 지정할 때 사용 | |
get_form() | 폼 인스턴스를 커스터마이징할 때 사용 | |
form_valid(form) | 폼 검증에 성공했을 때 호출 됨 주로 저장/처리 로직 작성 함 |
|
get_success_url() | 작업 성공 후 이동할 URL을 동적으로 반환할 때 사용 | |
get_context_data() | 템플릿에 넘길 context 데이터를 확장/커스터마이징할 때 사용 | |
get(), post(), patch(), delete() 등 | 요청 메소드 처리에 사용 |
1. CreateView
객체를 생성하는 폼을 제공하고 제출된 데이터를 저장하는 뷰 클래스이다.
model, success_url(혹은 get_success_url() 메소드) 을 필수속성으로 갖는다.
* models.py에 get_absolute_url() 메소드 정의 되어있으면 success_url 없어도 됨
* 즉, success_url, get_success_url(), get_absolute_url() 셋 중 하나는 작성되어야 함!!
📌 사용예시)
class BlogCreateView(LoginRequiredMixin, CreateView):
model = Blog # 어떤 모델에 저장할지 (필수 속성)
template_name = 'blog_form.html' # 랜더링할 템플릿 지정
# fields = ('category', 'title', 'content') # forms.py 대신으로 이렇게 사용함
form_class = BlogPostForm # 사용할 폼 클래스 (fields 대신 사용, 동시 사용 불가)
def form_valid(self, form): # 폼이 유효할 때 실행됨
self.object = form.save(commit=False) # 유저정보를 담은 후 저장하기 위함
self.object.author = self.request.user # 유저정보 할당
self.object.save()
return HttpResponseRedirect(self.get_success_url())
def get_success_url(self): # 저장 성공 시 이동할 URL (success_url 속성으로 할당 가능) (필수)
return reverse_lazy('blog:detail', kwargs={'pk':self.object.pk})
def get_context_data(self, **kwargs): # 템플릿에 넘겨줄 데이터가 있을 경우 사용
context = super().get_context_data(**kwargs)
context['sub_title'] = '작성'
context['btn_name'] = '생성'
return context
2. UpdateView
기존 객체의 정보를 수정하는 폼을 제공하고 수정된 데이터를 저장하는 뷰 클래스이다.
model, success_url(혹은 get_success_url() 메소드) 을 필수속성으로 갖는다.
* models.py에 get_absolute_url() 메소드 정의 되어있으면 success_url 없어도 됨
* 즉, success_url, get_success_url(), get_absolute_url() 셋 중 하나는 작성되어야 함!!
📌 사용예시)
class BlogUpdateView(LoginRequiredMixin, UpdateView):
model = Blog # 필수속성
template_name = 'blog_form.html'
form_class = BlogPostForm
def get_queryset(self): # 수정할 현재 데이터 불러옴
queryset = super().get_queryset()
if self.request.user.is_superuser:
return queryset # superuser면 전체 쿼리 반환
return queryset.filter(author=self.request.user) # superuser 아니면 해당 user 정보의 쿼리만 출력
def form_valid(self, form):
print(form.cleaned_data) # cleaned_data : 출력값을 정리해서 보여줌
return super().form_valid(form)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['sub_title'] = '수정'
context['btn_name'] = '수정'
return context
3. ListView
특정 모델에 대한 객체 목록을 조회하고 이를 템플릿에 전달해서 랜더링하는 뷰 클래스이다.
📌 사용예시)
class BlogListView(ListView):
# model = Blog => Blog.objects.all() 과 같음 // order_by() 등 함수사용 시 아래와 같이 작성
# queryset = Blog.objects.all().order_by('-created_at') # 혹은 ordering 변수로 선언할 수 있음
queryset = Blog.objects.all()
ordering = ('-created_at',)
template_name = 'blog_list.html'
paginate_by = 10
# for문에 들어가는 model 데이터들을 obejct_list 라는 변수명으로 받는다.
# 그래서 object_list 변수명을 사용해야 함!!
def get_queryset(self):
queryset = super().get_queryset()
q = self.request.GET.get('q')
if q:
queryset = queryset.filter(
Q(title__icontains=q) |
Q(content__icontains=q)
)
return queryset
4. DetailView
DB에 저장된 특정 객체 1개를 상세히 보여주는 뷰 클래스이다.
URL에 식별자(pk, id, slug 등)을 받아서 해당 객체를 가져와 템플릿에 전달한다.
📌 사용예시)
class UserProfileView(DetailView):
model = User
template_name = 'profile/detail.html'
slug_field = 'nickname'
slug_url_kwarg = 'slug'
queryset = User.objects.all()\
.prefetch_related('post_set', 'post_set__images', 'following', 'followers')
5. DeleteView
특정 객체를 삭제할 수 있는 뷰 클래스이다.
삭제 확인용 템플릿을 보여주고 POST 요청 시 삭제가 실행된다.
📌 사용예시)
class BlogDeleteView(LoginRequiredMixin, DeleteView):
model = Blog
def get_queryset(self):
queryset = super().get_queryset()
if not self.request.user.is_superuser:
return queryset.filter(author=self.request.user)
return queryset
def get_success_url(self):
return reverse_lazy('blog:list')
3. request(요청) 처리 |
구분 | 설명 | 코드 예시 |
request.user | 현재 요청을 보낸 로그인된 사용자 정보 | request.user.username, request.user.is_authenticated |
request.POST | POST 요청으로 전달된 데이터 (form 전송 등) |
request.POST.get('title') |
reuquest.GET | GET요청의 쿼리 파라미터 (검색, 필터 등) |
request.GET.get('q') |
request.FILES | 업로드된 파일 데이터 접근 | request.FILES['image'] |
request.method | 요청방식(GET, POST 등) | if request.method == 'POST': pass |
4. response(응답) 관련 함수 |
구분 | 설명 | 예시코드 |
HttpResponseRedirect() | 특정 URL로 리다이렉트 (페이지 이동) |
return HttpResponseRedirect('/login/') |
HttpResponse() | 직접 문자열, HTML 등을 반환 (단순 응답) |
return HttpResponse("Hello World") |
status code | 응답 상태를 나타내는 숫자 코드 | return HttpResponse ("Forbidden", status=403) |
response data | JSON 형식으로 응답 | {"title":"제목1", "content":"본문1"} |
📌 status code
상태코드 | 설명 |
200 | 요청 성공 |
302 | 리다이렉트 |
400 | 잘못된 요청 |
403 | 권한 없음 |
404 | 존재하지 않음 |
500 | 서버오류 |
반응형
'Backend > Django' 카테고리의 다른 글
[Django] Django 학습 정리 - Django Mail (0) | 2025.03.31 |
---|---|
[Django] Django 학습 정리 - Django Auth (0) | 2025.03.30 |
[Django] Django 학습 정리 - Django ORM (0) | 2025.03.29 |
[Django] Django 학습 정리 - Django Form (0) | 2025.03.29 |
[Django] Django 학습 정리 - FBV(Function Based View)와 URL (0) | 2025.03.29 |
댓글