class형 View는 URLconf에서 시이작!!
- 클래스로 작성되어 있는 뷰 객체를 말한다.
- 상속과 믹스인 기능 사용으로 코드의 재사용이 가능
- 뷰의 체계적 관리
- 제네릭 뷰 작성
from django.urls import path
from posting.views import PostView, PostCommentView,PostLikeView
urlpatterns = [
path('/create', PostView.as_view()),
path('/read', PostView.as_view()), # 전체 포스트 조회기능
path('/create/<int:pk>/comment', PostCommentView.as_view()), # 댓글 생성
path('/read/<int:pk>/comment', PostCommentView.as_view()), # 댓글 조회
path('/create/<int:pk>/like', PostLikeView.as_view()), # 좋아요 등록
path('/delete/<int:pk>/like', PostLikeView.as_view()), # 좋아요 등록
path('/read/<int:pk>/like', PostLikeView.as_view()), # 좋아요 조회
]
URL패턴에서 어떻게 클래스 View로 넘어갈까요? 그건~!
as_view()
덕분입니다. 인스턴스 생성
dispatch()
메서드를 호출.dispatch()
는 HTTP메서드 GET, POST중 어느것인지 파악해요.HttpResponseNotAllowed
Error 발생!class PostView(View):
def post(self, request):
try:
data = json.loads(request.body)
user = User.objects.get(email=data['email'])
title = data['title']
content = data['content']
image_url = data['image_url']
p = re.compile('^([12]\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01]))$')
if not title and content and image_url:
return JsonResponse({'MESSAGE': "YOUR REQUEST IS NOT ADEQUATE!"},status=400)
if not Post.objects.filter(title=title).exists():
Post.objects.create(
user = user, # 객체로 지정해야함 다른 속성값으로 하면 오류 발생함!
title = title,
content = content,
image_url = image_url,
)
return JsonResponse({'MESSAGE': 'POST REQUEST SUCCEEDED!'}, status=200)
return JsonResponse({'MESSAGE': 'TITLE ALREADY EXISTS!'}, status=400)
except KeyError:
return JsonResponse({'MESSAGE': 'KEY ERROR OCCURED!'},status=400)
except ValueError:
return JsonResponse({'MESSAGE': 'VALUE ERROR OCCURED!'},status=400)
except User.DoesNotExist:
return JsonResponse({'MESSAGE':'USER DOES NOT EXISTS!'},status=400)
except Post.DoesNotExist:
return JsonResponse({'MESSAGE':'POST DOES NOT EXISTS!'},status=400)
def get(self, request):
try:
posts = Post.objects.all()
post_list = []
for i in posts:
post_list.append(
{
'posts.id' :i.id,
'posts.user' :i.user.email,
'posts.title' :i.title,
'posts.content' :i.content,
'posts.created' :i.created_dt,
'posts.image_url' :i.image_url,
}
)
return JsonResponse({'RESULT':post_list }, status=200)
except KeyError:
return JsonResponse({'MESSAGE': 'KEY ERROR OCCURED!'},status=400)
except ValueError:
return JsonResponse({'MESSAGE': 'VALUE ERROR OCCURED!'},status=400)
except Post.DoesNotExist:
return JsonResponse({'MESSAGE':'POST DOES NOT EXISTS!'},status=400)
MyView 클래스는 View 클래스를 상속 받음
View 클래스에는 as_view()
메서드와 dispatch()
메소드가 정의되어 있음.
하나! GET, POST 등의 HTTP 메소드에 따른 처리를 메소드명으롤 구분 할 수 있어, 좀 더 깔끔한 구조의(IF 문이 없는)코드를 생산할 수 있다.
둘! 다중상속이 가능하여 코드 재사용성과 개발 생산성 UP!
from django.http import HttpResponse
from django.views.generic import ListView
from books.models import Book
class BookListView(ListView):
model = Book
def head(self, *args, **kwargs):
last_book = self.get_queryset().latest('publication_date')
response = HttpResponse('')
response['Last-Modified'] = last_book.publication_date.strftime('%a, %d %b %y %H:%M:%S GMT')
return response
위 예제는 서점에 방문한 직후에 새롭게 출간된 책이 있는지를 문의하는 로직이다. 최근 발간된 책이 없는데도 책 리스트를 서버로부터 받아 오게되면 네트워크 대역폭이 낭비되므로, 이를 방지하기 위해 HEAD 메소드를 사용한다. HEAD 요청에 대한 응답은 바디 없이 헤더만 보내주면 된다.
대부분의 클래스형 뷰는 장고가 주는 GENERIC VIEW를 상속 받아서 작성해요.
Generic View란?
공통적으로 사용하는 기능들을 추상화하여 장고에서 기본 제공형태로 만들어진 클래스형뷰.
Django 에서 제공하는 제네릭 뷰는 다음과 같이 4가지로 분류할 수 있다.
아래는 위 4가지 분류에 따른 구체 뷰 클래스에 대한 설명을 보여준다.