FBV Functioon based View ( 뷰에서 함수 씀 )
CBV Class based View ( 뷰에서 클래스 씀)
ListView를 이용한 CBV (코드는 gpt를 이용하여 생성했습니다. 설명은 제가 책을 보고 추가)
기본 모델 작성
# models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
뷰 정의
class 따로 만드는 방법도 있겠지만, 그부분은 아직 학습이 안되어있으니 장고에 기본으로 있는 ListView를 이용한 방법
# views.py
from django.views.generic import ListView, DetailView
from .models import Post
class PostList(ListView):
model = Post
template_name = 'blog/post_list.html'
context_object_name = 'posts'
class PostDetail(DetailView):
model = Post
template_name = 'blog/post_detail.html'
context_object_name = 'post'
여기서 추가로 집고갈 점은 template_name 지정인데,
기본적으로 ListView는 "모델명_list.html" 파일을 template_name으로 설정한다는 것이다.
마찬가지로 DetailView도 "모델명_detail.html"을 기본 템플릿으로 설정한다.
그러므로 위의 경우 post_list.html과 post_detail.html을 template로 갖는다면
# views.py
from django.views.generic import ListView, DetailView
from .models import Post
class PostList(ListView):
model = Post
# template_name = 'blog/post_list.html'
context_object_name = 'posts'
class PostDetail(DetailView):
model = Post
# template_name = 'blog/post_detail.html'
context_object_name = 'post'
template_name없이 작성해도 문제가 되지 않는다.
url 설정
# urls.py
from django.urls import path
from . import views
urlpatterns = [
# CBV
path('', views.PostList.as_view(), name='post_list'),
path('<int:pk>/', views.PostDetail.as_view(), name='post_detail'),
# FBV
# path('<int:pk>/', views.single_post_page, name='single_post_page'),
# path('', views.index, name='index'), # FBV
]
html
위에도 적었지만, ListView와 DetailView는 "모델네임_list.html", "모델네임_detail.html"을 기본으로 불러오기 때문에, 이와 다른패턴의 html 을 적용하고자 한다면 views.py의 template_name을 적어줘야한다.
# post_list.html
<!DOCTYPE html>
<html>
<head>
<title>Post List</title>
</head>
<body>
<h1>Post List</h1>
<ul>
{% for post in posts %}
<li><a href="{% url 'post_detail' post.pk %}">{{ post.title }}</a></li>
{% endfor %}
</ul>
</body>
</html>
# post_detail.html
<!DOCTYPE html>
<html>
<head>
<title>{{ post.title }}</title>
</head>
<body>
<h1>{{ post.title }}</h1>
<p>{{ post.content }}</p>
<p>Created at: {{ post.created_at }}</p>
</body>
</html>
여기서 post_list.html은 for loop을 posts를 갖고 진행했는데
이는 views.py에서 context_object_name 을 설정 했기 때문이다.
만약 context_object_name을 선언하지 않았다면 ListView는 "모델명_list" 혹은 "object_list"를 컨텍스트 변수로 가져온다.
# views.py
from django.views.generic import ListView, DetailView
from .models import Post
class PostList(ListView):
model = Post
# template_name = 'blog/post_list.html'
# context_object_name = 'posts'
class PostDetail(DetailView):
model = Post
# template_name = 'blog/post_detail.html'
context_object_name = 'post'
# post_list.html
<!DOCTYPE html>
<html>
<head>
<title>Post List</title>
</head>
<body>
<h1>Post List</h1>
<ul>
{% for post in post_list %}
<li><a href="{% url 'post_detail' post.pk %}">{{ post.title }}</a></li>
{% endfor %}
</ul>
</body>
</html>
# post_detail.html
<!DOCTYPE html>
<html>
<head>
<title>{{ post.title }}</title>
</head>
<body>
<h1>{{ post.title }}</h1>
<p>{{ post.content }}</p>
<p>Created at: {{ post.created_at }}</p>
</body>
</html>
아, DetailView는 컨텍스트를 지정하지 않는다면 모델명을 가져온다. 위의경우엔 post
'Code > Django' 카테고리의 다른 글
django wagtail에서 ajax 구현 방식 (0) | 2024.07.31 |
---|---|
wagtail MEDIA_URL 연결 (0) | 2024.07.29 |
url view 추가하기 FBV (0) | 2024.06.26 |
Django + Wagtail Start (0) | 2024.05.10 |
가상환경부터 django 프로젝트 생성까지(mac, terminal, venv. no pycharm) (0) | 2024.01.17 |