클래스형 뷰
가 개발자들이 자주 쓰는 기능들을상위 클래스
로상속
받아 사용한다면, 제네릭 뷰는상속
받을 수 있는이미 만들어진 상위 클래스
를 말한다.
CRUD
에서Read
에 해당하는 클래스형 함수를 만들 때, 모델에 접근해 데이터를 불러오는 코드를 직접 작성하지 않고도ListView
또는DetailView
제네릭 뷰를 상속받으면 접근할모델
과 렌더할템플릿
만 작성하면 된다.
이전 포스팅에 작성된
클래스형 함수
PostCreateView
는 장고의View
를 상속받아 작성됐다.제네릭 뷰
를 상속받아 더 간편하게CRUD
의CREATE
기능을 구현하는 방법을 알아본다.
기존에 작성된 코드와
제네릭뷰
(CreateView)를 상속받아 작성된 코드를 비교해보자.
기존에 작성된 코드는 아래와 같다.
# class PostCreateView(View):
# def get(self, request):
# post_form = PostForm()
# context = {"post_form": post_form}
# return render(request, 'posts/post_form.html', context=context)
# 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)
# else:
# context = {"post_form": post_form}
# return render(request, 'posts/post_form.html', context=context)
제네릭 뷰
(CreateView)를 상속받아 다시 작성된 코드는 아래와 같다.
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})
아래의 코드는 접근할
모델
, 사용할폼
, 렌더할템플릿
, 그리고 게시글 생성 후 이동할url
만 작성했지만 기능은 일치한다.
그 이유는 상속받은
CreateView
제네릭 뷰에서 다른 내용들을 포함하고 있기 때문이다.
CreateView
는 사용할폼
을 템플릿에 전달할 때context
에{"form": {사용할 폼}}
을 전달한다. 따라서 기존에context
로 전달하는폼
의키
가 다른 이름이라면템플릿에서 변경
해야 한다.
<dear>
프로젝트에서는 기존에는{"post_form":PostForm}
으로 전달 했는데키
가post_form
에서form
으로 변경되어 전달되기 때문에템플릿
에서 해당 부분만 변경하면 된다.
reverse
함수는redirect
과는 다르게 url을 문자열로 생성하고 반환하는 역할만 한다.CreateView
제네릭 뷰에서 이미 해당 url로 이동하는 기능을 내장하고 있기 때문에reverse
를 사용하는 것 같다.정확한 이해를 위해 각종 블로그를 찾아봤는데
redirect
는 url 경로가 변경되면 변경된 경로를 모두 찾아 수정해야하고reverse
는name
속성을 이용해 경로를 수정하지 않아도 된다는 내용이 많았다.그러나
redirect
도 마찬가지로name
속성을 이용하면 url 경로를 하드코딩하지 않아도 되기 때문에 변경된 경로를 모두 찾아 수정할 필요가 없지 않나 라는 의문이 들었다.해당 의문에 대한 명확한 답을 찾게된다면 다시 정리해서 수정하겠다.
url 패턴에서
post_create
를PostCreateView
로 변경해야 한다.
urls.py
urlpatterns = [
# path('', views.index),
path('', views.PostListView.as_view(), name="post-list"),
path('posts/new/', views.PostCreateView.as_view(), name="post-create"),
path('posts/<int:post_id>/', views.PostDetailView.as_view(), name="post-detail"),
path('posts/<int:post_id>/edit/', views.post_update, name="post-update"),
path('posts/<int:post_id>/delete/', views.post_delete, name="post-delete"),
]