장고8
클래스형 뷰
개발자들이 자주 쓸만한 뷰를 클래스로 만들어 둔 것을 클래스형 뷰라고 한다.
def post_create(request):
if request.method == 'POST':
post_form = PostForm(request.POST)
if post_form.is_valid():
new_post = post_form.save()
return redirect('post-detail', post_id=new_post.id)
else:
post_form = PostForm()
return render(request, 'posts/post_form.html', {'form':post_form})
기존의 함수형 뷰를 클래스형 뷰로 수정해보면
from django.views import View
class PostCreateView(View):
def get(self, request):
post_form = PostForm()
return render(request, 'posts/post_form.html', {'form':post_form})
def post(self, request):
post_form = PostForm(request.POST)
if post_form.is_valid():
new_post = post_form.save()
return redirect('post-detail', post_id=new_post.id)
return render(request, 'posts/post_form.html', {'form': post_form})
이렇게 상속을 받아서 편하게 작성할 수 있다.
그리고 urls에서는
path(‘posts/new’, views.PostCreateView.as_view(), name=’post-create’)
이렇게 .as_view()를 붙여줘야 한다.
제네릭 뷰
개발자들이 자주 쓸만한 뷰를 하나의 형태로 만들어 둔 것을 제네릭 뷰라고 한다.
CreateView
from django.views.generic import CreateView
from django.urls import reverse
class PostCreateView(CreateView):
model = Post
form_class = PostForm
template_name = 'posts/post_form.html'
def get_success_url(self):
return reverse('post-detail', kwargs={'post_id': self.object.id})
이런식으로 사용하면 된다.
정상적으로 작성이 됐을 때 페이지를 이동하도록 get_success_url을 만든다.
reverse함수는 url-name으로 이용한 실제 url을 리턴한다. 이 때 필요한 키워드를 kwargs파라미터로 전달할 수 있다.
urls에서 as_view를 사용하도록 수정한다.
ListView
def post_list(request):
posts = Post.objects.all()
paginator = Paginator(posts, 6)
curr_page_number = request.GET.get('page')
if curr_page_number is None:
curr_page_number = 1
page = paginator.page(curr_page_number)
return render(request, 'posts/post_list.html', {'page': page})
기존에 이렇게 작성했던 것을
from django.views.generic import ListView
class PostListView(ListView):
model = Post
template_name = 'posts/post_list.html'
context_object_name = 'posts'
ordering = ['-dt_created']
paginate_by = 6
page_kwargs = 'page'
이렇게 수정하면 된다.
page_kwarg는 쿼리 스트링으로 부터 현재 페이지에 대한 번호를 가져올 때 사용할 키워드를 적어주는 부분이다.
context_object_name은 뷰에서 컨텍스트 변수명을 별도로 정해준다.
사용하지 않으면 object_list변수에 객체를 할당하게 된다.
urls에서 as_view를 사용하도록 수정하고
템플릿에서는 기존에는 page키워드로 받았던 것을 page_obj키워드로 받도록 수정한다. 제네릭 ListView는 페이지네이션을 적용해서 각각의 페이지를 page_obj라는 context로 전달하기 때문이다.
DetailView
def post_detail(request, post_id):
post = get_object_or_404(Post, id=post_id)
context = {"post":post}
return render(request, 'posts/post_detail.html', context)
기존의 방식에서
from django.views.generic import DetailView
class PostDetailView(DetailView):
model = Post
template_name = 'posts/post_detail.html'
pk_url_kwarg = 'post_id'
context_object_name = 'post'
이렇게 수정하면 된다.
pk_url_kwarg는 urls.py에서 URL 패턴에 있는 데이터를 조회할 키워드의 이름을 적어주는 부분이다.
UpdateView
def post_update(request, post_id):
post = get_object_or_404(Post, id=post_id)
if request.method == 'POST':
post_form = PostForm(request.POST, instance=post)
if post_form.is_valid():
post_form.save()
return redirect('post-detail', post_id=post.id)
else:
post_form = PostForm(instance=post)
return render(request, 'posts/post_form.html', {'form': post_form})
기존의 코드에서
from django.views.generic import UpdateView
class PostUpdateView(UpdateView):
model = Post
form_class = PostForm
template_name = 'posts/post_form.html'
pk_url_kwarg = 'post_id'
def get_success_url(self):
return reverse('post-detail', kwargs={'post_id': self.object.id})
이렇게 수정
DeleteView
def post_delete(request, post_id):
post = get_object_or_404(Post, id=post_id)
if request.method == 'POST':
post.delete()
return redirect('post-list')
else:
return render(request, 'posts/post_confirm_delete.html', {'post': post})
기존의 코드
class PostDeleteView(DeleteView):
model = Post
template_name = 'posts/post_confirm_delete.html'
pk_url_kwarg = 'post_id'
context_object_name = 'post'
def get_success_url(self):
return reverse('post-list')
수정된 코드
404처리까지 자동으로 된다.
제네릭 뷰 context
템플릿으로 전달되는 model데이터
ListView -> ‘object_list’, ‘[모델명]_list’
DetailView -> ‘object’, ‘[모델명]’
CreateView -> 없음
UpdateView -> ‘object’, ‘[모델명]’
DeleteView -> ‘object’, ‘[모델명]’
context_object_name을 설정하면 값이 변경되어서 넘어간다.
ListView에서 context_obejct_name = ‘page’라고 했으면 ‘object_list’와 ‘page’ 두가지가 넘어가게 된다.
ListView에서 템플릿으로 전달하는 context
-
paginator
페이지네이션을 적용하면 장고에서 제공하는 페이지네이터 객체가 전달된다.
기본값으로는 None으로 페이지네이션이 적용되어 있지 않다.
페이지네이션을 적용하려면 리스트뷰에서 pageinated_by를 작성해야 한다. -
page_obj
페이지네이션을 적용하면 현재 Page객체가 전달된다. -
is_paginated
기본값은 False이고 페이지네이션을 적용하면 True가 된다. -
object_list, [모델명]_list
현재 Page에 있는 데이터 목록이 전달된다.
제네릭 뷰 정리
- Base Views
-
TemplateView
template_name -> 렌더할 템플릿을 지정하는 속성: None -
RedirectView
url -> 이동할 url을 지정하는 속성, 기본값: None
pattern_name -> url패턴의 이름을 지정하는 속성, 기본값: None
query_string -> 쿼리 스트링을 전달할 지 여부, 기본값: False
-
- Display Views
-
ListView
model -> 사용할 모델 지정, 기본값: None
ordering -> 데이터 정렬 속성 지정, 기본값: None
paginate_by -> 페이지에 표시 할 데이터의 수, 기본값: None
page_kwarg -> 쿼리스트링으로부터 가져올 현재 페이지에 대한 키워드, 기본값: ‘page’
template_name -> 렌더할 템플릿을 지정하는 속성, 기본값: None
context_object_name -> 템플릿으로 전달할 모델의 context 키워드 지정, 기본값: ‘[model_name]_list’ -
DetailView
model -> 사용할 모델 지정, 기본값: None
pk_url_kwarg -> urls.py에서 지정한 키워드 인수, 기본값: ‘pk’
template_name -> 렌더할 템플릿을 지정하는 속성, 기본값: None
context_object_name -> 템플릿으로 전달할 모델의 context 키워드 지정, ‘[model_name]’
-
- Edit Views
-
FormView
form_class -> 입력을 위한 Form Class를 지정, 기본값: None
success_url -> 처리가 성공했을 때 리디렉션 할 URL을 지정, 기본값: None
template_name -> 렌더할 템플릿을 지정하는 속성, 기본값: None -
CreateView
model -> 사용할 모델 지정, 기본값: None
form_class -> 입력을 위한 Form Class를 지정, 기본값: None
fields -> 데이터 입력에 사용할 필드를 명시적으로 지정, 기본값: None
template_name -> 렌더할 템플릿을 지정하는 속성, 기본값: None
pk_url_kwarg -> urls.py에서 지정한 키워드 인수, 기본값: ‘pk’
success_url -> 처리가 성공했을 때 리디렉션 할 URL을 지정, 기본값: None -
UpdateView
model -> 사용할 모델 지정, 기본값: None
form_class -> 입력을 위한 Form Class를 지정, 기본값: None
fields -> 데이터 입력에 사용할 필드를 명시적으로 지정, 기본값: None
template_name -> 렌더할 템플릿을 지정하는 속성, 기본값: None
pk_url_kwarg -> urls.py에서 지정한 키워드 인수, 기본값: ‘pk’
success_url -> 처리가 성공했을 때 리디렉션 할 URL을 지정, 기본값: None
context_object_name -> 템플릿으로 전달할 모델의 context 키워드 지정, 기본값: ‘[model_name]’ -
DeleteView
model -> 사용할 모델 지정, 기본값: None
template_name -> 렌더할 템플릿을 지정하는 속성, 기본값: None
pk_url_kwarg -> urls.py에서 지정한 키워드 인수, 기본값: ‘pk’
success_url -> 처리가 성공했을 때 리디렉션 할 URL을 지정, 기본값: None
context_object_name -> 템플릿으로 전달할 모델의 context 키워드 지정, 기본값: ‘[model_name]’
-
- Date Views
- YearArchiveView
- MonthArchiveView
- DayArchiveView
- TodayArchiveView
context
Context는 View에서 Template으로 전달되어 렌더링시 사용할 수 있는 사전형 데이터 변수다.
render함수에서 세번째 파라미터로 사용했던 부분이다.
- CreateView
- form -> form_class 클래스 변수에 명시한 폼이 전달된다.
- ListView
- paginator -> Paginator 객체가 전달된다.
- page_obj -> 현재 Page 객체가 전달된다.
- is_paginated -> 페이지네이션 적용 여부가 boolean 형으로 전달된다.
- UpdateView
- form -> form_class 클래스 변수에 명시한 폼이 전달된다.
더 간단하게
-
template_name
ListView에서 template_name의 기본값은 [model_name]_list.html이다.
DetailView에서 template_name의 기본값은 [model_name]_detail.html이다.
CreateView에서 template_name의 기본값은 [model_name]_form.html이다.
UpdateView에서 template_name의 기본값은 [model_name]_form.html이다.
DeleteView에서 template_name의 기본값은 [model_name]_confirm_delete.html이다.
템플릿의 이름을 기본값과 일치하게 작성했다면 생략해도 된다. -
page_kwarg
page_kwarg의 기본값은 page이다.
템플릿에서 page를 키워드로 사용하고 있다면 생략해도 된다. -
pk_url_kwarg
pk_url_kwarg의 기본값은 pk이다.
views.py에서 url패턴에 있는 데이터 조회를 위한 키워드(<\int:pk>)를 pk로 사용한다면 생략해도 된다.
Leave a comment