CBV란?
- 클래스 기반 뷰 != 제네릭 뷰
- 클래스로 HttpResponse를 리턴하면 그것도 클래스 기반 뷰라고 볼 수 있음
- 실무에서는 클래스 기반 뷰를 제네릭 뷰라고 혼용해서 많이 부름
- 제네릭 뷰 : 장고에서 제공하는 여러 기능을 미리 구현해놓은 클래스 기반 뷰
Base views
View : 최상위 제네릭 뷰, 기본 뷰, django view를 만드는데 필요한 기능 제공
TemplateView : 템플릿이 주어지면 렌더링을 해주는 뷰
RedirectView : URL이 주어지면 리다이렉트 해주는 뷰
Generic display views
DetailView : model과 템플릿 받아 조건에 맞는 상세 오브젝트를 보여줍니다.
ListView : model과 템플릿 받아 전체 오브젝트를 보여줍니다.
Generic editing views
FormView : 폼을 보여주고 처리합니다.
CreateView : 폼을 보여주고 객체를 생성합니다.
UpdateView : 폼을 조건에 맞게 보여주고 객체를 수정합니다.
DeleteView : 객체를 삭제합니다.
Generic date views
ArchiveIndexView : 조건에 맞는 객체의 날짜 정보를 출력합니다.
YearArchiveView : 연도에 맞는 객체를 출력합니다.
MonthArchiveView : 월에 맞는 객체를 출력합니다.
WeekArchiveView : 주에 맞는 객체를 출력합니다.
DayArchiveView : 일에 맞는 객체를 출력합니다.
TodayArchiveView : 오늘 날짜에 객체를 출력합니다.
DateDetailView : 연, 월, 일 조건에 맞는 객체를 출력합니다.
[참조 : 공식문서]
- https://docs.djangoproject.com/en/5.0/ref/class-based-views/
- ListVeiw : https://docs.djangoproject.com/en/5.0/ref/class-based-views/generic-display/
- CreateView : https://docs.djangoproject.com/en/5.0/ref/class-based-views/generic-editing/
예제 코드
베이스 세팅
# [blog/urls.py]
from django.urls import path
from . import views
urlpatterns = [
path("", views.blog_list, name="blog_list"),
path("<int:pk>/", views.blog_detail, name="blog_detail"),
path("write/", views.blog_write, name="blog_write"),
path("edit/<int:pk>/", views.blog_edit, name="blog_edit"),
path("delete/<int:pk>/", views.blog_delete, name="blog_delete"),
path("test/", views.test, name="test"),
]
# [blog/models.py]
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=50)
contents = models.TextField()
head_image = models.ImageField(
upload_to='blog/images/%Y/%m/%d/', blank=True)
file_upload = models.FileField(
upload_to='blog/files/%Y/%m/%d/', blank=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateField(auto_now=True)
def __str__(self):
return self.title
Class Base로 뷰 작성하기
# [blog/views.py]
from django.db.models.query import QuerySet
from django.views.generic import (
ListView, DetailView, CreateView, UpdateView, DeleteView
)
from .models import Post
from django.urls import reverse_lazy, reverse
from django.http import HttpResponse
from django.db.models import Q
class PostList(ListView):
model = Post
ordering = "-pk" # 내림차순 정렬을 하겠다~
# template_name = "blog/파일명.html" # 기본값 : blog/post_list.html
def get_queryset(self):
queryset = super().get_queryset()
q = self.request.GET.get('q', '')
if q :
queryset = queryset.filter(
Q(title__icontains=q) | Q(contents__icontains=q)
).distinct()
return queryset
class PostDetail(DetailView):
model = Post
class PostCreate(CreateView):
model = Post
fields = '__all__'
# fields = ['title', 'content', 'image']
# template_name = "blog/파일명.html" # 기본값 : blog/post_form.html
success_url = reverse_lazy("blog_list")
''' reverse_lazy 사용 이유 :
object생성 후에 url로 이동해야 하는데 reverse는 함수이기 때문에 함수 실행 시점에 url로 이동해버림.
post 생성 후에 url로 이동해야 하므로 lazy 걸어줌
'''
class PostUpdate(UpdateView):
model = Post
fields = "__all__"
# fields = ["title", "content", "image"]
# template_name = "blog/내가_원하는_파일명.html" # 기본값: blog/post_form.html
# success_url = reverse_lazy("blog_list")
def get_success_url(self):
return reverse('blog_detail', args=[str(self.object.pk)])
'''
success_url = reverse_lazy("blog_list") : 정적인 페이지로 보낼 때. 상세 페이지로는 못감.
def get_success_url : 동적인 페이지로 보낼 수 있음. pk 넣어서 상세페이지로 보낼 수 있음.
'''
class PostDelete(DeleteView):
model = Post
success_url = reverse_lazy("blog_list")
class PostTest(CreateView):
model = Post
def get(self, request):
return HttpResponse("get 요청이 왔습니다.")
def post(self, request):
return HttpResponse("post 요청이 왔습니다.")
# 실무에서는 urls.py에서 바로 as_view() 붙여서 사용.
# views.PostList.as_view() 요런식으로
blog_list = PostList.as_view()
blog_detail = PostDetail.as_view()
blog_write = PostCreate.as_view()
blog_edit = PostUpdate.as_view()
blog_delete = PostDelete.as_view()
test = PostTest.as_view()
''' CBV 사용 시 템플릿 네이밍 규칙
PostList (ListView)
템플릿 이름 규칙: <app_name>/<model_name_소문자>_list.html
여기서의 기본 템플릿: <app_name>/post_list.html
템플릿 접근 방법:
{% for post in object_list %}
{{ post.title }}
{% endfor %}
PostDetail (DetailView)
템플릿 이름 규칙: <app_name>/<model_name_소문자>_detail.html
여기서의 기본 템플릿: <app_name>/post_detail.html
템플릿 접근 방법:
{{ object.title }}
PostCreate (CreateView)
템플릿 이름 규칙: <app_name>/<model_name_소문자>_form.html
여기서의 기본 템플릿: <app_name>/post_form.html
템플릿 접근 방법:
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Create</button>
</form>
PostUpdate (UpdateView) ** CreateView와 같음
템플릿 이름 규칙: <app_name>/<model_name_소문자>_form.html
여기서의 기본 템플릿: <app_name>/post_form.html
템플릿 접근 방법:
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Update</button>
</form>
PostDelete (DeleteView)
템플릿 이름 규칙: <app_name>/<model_name_소문자>_confirm_delete.html
여기서의 기본 템플릿: <app_name>/post_confirm_delete.html
템플릿 접근 방법:
<form method="post">
{% csrf_token %}
Are you sure you want to delete "{{ object.title }}"?
<button type="submit">Delete</button>
</form>
'''
'공부 > Django' 카테고리의 다른 글
Lightsail로 Django DRF https 배포하기 - 2. Github Actions ci/cd 연결 (0) | 2024.04.25 |
---|---|
Lightsail로 Django DRF https 배포하기 - 1. 서버세팅 (1) | 2024.04.25 |
CBV로 Django auth 구현 (0) | 2024.02.27 |
forms.py 이용해 웹 페이지에서 CRUD하기 (0) | 2024.02.26 |
장고 Model 세팅 + Q검색 (0) | 2024.02.25 |