bookmark/model.py
from django.db import models
class Bookmark(models.Model):
title = models.CharField('TITLE', max_length=100, blank=True)
url = models.URLField('URL', unique=True)
def __str__(self):
return self.title
👉 bookmarkApp에서는 간단한 링크를 통해 해당 웹페이지로 연결되는 기능을 구현할 것이다.
간단히 title과 url만 만들었다.
blog/model.py
from django.db import models
from django.urls import reverse
class Post(models.Model):
title = models.CharField(verbose_name='TITLE', max_length=50)
slug = models.SlugField('SLUG', unique=True, allow_unicode=True, help_text='one word for title alias.')
description = models.CharField('DESCRIPTION', max_length=100, blank=True, help_text='simple description text.')
content = models.TextField('CONTENT')
create_dt = models.DateTimeField('CREATE DATE', auto_now_add=True)
modify_dt = models.DateTimeField('MODIFY DATE', auto_now=True)
class Meta:
verbose_name = 'post' #테이블 단수 별칭
verbose_name_plural = 'posts' #테이블 복수 별칭
db_table = 'blog_posts' #디폴트는 앱명_모델명(blog_post)
ordering = ('-modify_dt',) #출력 시 modify_dt를 기준으로 내림차순 정렬
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('blog:post_detail', args=(self.slug,))
def get_previous(self):
return self.get_previous_by_modify_dt()#장고의 내장함수, modify_dt()를 기준으로 최신포스트를 반환
def get_next(self):
return self.get_next_by_modify_dt()
👉 blogApp에서는 글이 작성된 시각(create_dt), 글이 수정된 시각(modify_dt), 제목, 설명, 내용, 각각의 글을 가리킬 별칭(slug)을 저장해야한다.
slug는 게시물 검색에 쓰인다.
website/urls.py
from django.contrib import admin
from django.urls import path, include
from mysite.views import HomeView
#from bookmark.views import BookmarkLV, BookmarkDV
urlpatterns = [
path('admin/', admin.site.urls),
path('', HomeView.as_view(), name='home'),
path('bookmark/', include('bookmark.urls')),
path('blog/', include('blog.urls')),
]
👉 북마크와 블로그에 관련된 url은 해당 앱의 urls.py로 보내줄 것이다. include()를 통해서 보내주면 된다.
/bookmark/urls.py
from django.urls import path
from bookmark.views import BookmarkLV, BookmarkDV
app_name = 'bookmark'
urlpatterns = [
path('', BookmarkLV.as_view(), name='index'),
path('<int:pk>/', BookmarkDV.as_view(), name='detail'),
]
/blog/urls.py
from django.urls import path, re_path
from blog import views
app_name = 'blog'
urlpatterns = [
#/blog/
path('', views.PostLV.as_view(), name='index'),
#/blog/post/
path('post/', views.PostLV.as_view(), name='post_list'),
#/blog/post/django-example
re_path(r'^post/(?P<slug>[-\w]+)/$', views.PostDV.as_view(), name='post_detail'),
#/blog/archive/
path('archive/', views.PostAV.as_view(), name='post_archive'),
#/blog/archive/2019/
path('archive/<int:year>/', views.PostYAV.as_view(), name='post_year_archive'),
#/blog/archive/2019/nov/
path('archive/<int:year>/<str:month>/', views.PostMAV.as_view(), name='post_month_archive'),
#/blog/archive/2019/nov/10/
path('archive/<int:year>/<str:month>/<int:day>/', views.PostDAV.as_view(), name='post_day_archive'),
#/blog/archive/today/
path('archive/today/', views.PostTAV.as_view(), name='post_today_archive'),
]
👉 블로그에는 archive기능을 추가할 것이다. 전체 글 조회 뿐만 아니라 년도, 월, 일 각각으로 나누어서 해당하는 게시물을 조회할 수 있다.
mysite/views.py
from django.views.generic import TemplateView
# TemplateView
class HomeView(TemplateView):
template_name = 'home.html'
bookmark/views.py
from django.views.generic import ListView, DetailView #클래스형 제네릭 뷰 임포트하기위해 ListView, DetailView클래스 임포트
from bookmark.models import Bookmark #테이블 조회를 위해 모델클래스 임포트
class BookmarkLV(ListView):
model = Bookmark
class BookmarkDV(DetailView):
model = Bookmark
blog/views.py
#클래스형 제네릭 뷰 임포트
from django.views.generic import ListView, DetailView
from django.views.generic.dates import ArchiveIndexView, YearArchiveView, MonthArchiveView
from django.views.generic.dates import DayArchiveView, TodayArchiveView
#테이블 조회를 위해 post모델 클래스를임포트
from blog.models import Post
# ListView
class PostLV(ListView):
model = Post #post테이블 가져옴
template_name = 'blog/post_all.html' #템플릿 파일을 지정한다. 지정하지 않을 경우 blog/post_list.html로 설정됨
context_object_name = 'posts' #템플릿 파일에 넘겨주는 객체명을 posts로 변경, 변경해도 기존의 'object_list를 사용할 수 있음
paginate_by = 2 #한 페이지에 보여주는 객체리스트의 숫자는 2로 설정. 장고가 페이징 기능을 제공함.
# DetailView
class PostDV(DetailView):
# DetailView 제네릭 뷰를 상속받아 PostDV 클래스형 뷰를 정의함.
# DetailView 제네릭 뷰는 테이블로부터 특정 객체를 가져와 그 객체의 상세 정보를 출력.
# 테이블에서 특정 객체를 조회하기 위한 키는 기본 키 대신 slug속성을 사용하고 있음.
# 이 slug파라미터는 URLconf에서 추출해 뷰로 넘겨줌.
model = Post
# ArchiveView
class PostAV(ArchiveIndexView):
model = Post # 대상 테이블
date_field = 'modify_dt' #기준이 되는 날짜 필드는 'modify_dt'를 사용함
make_object_list = True #해당 연도에 해당하는 객체의 리스트를 만들어서 템플릿에 넘겨줍니다. 템플릿 파일에서 object_list 컨텍스트 변수를 사용할 수 있다.
class PostYAV(YearArchiveView):
model = Post
date_field = 'modify_dt'
class PostMAV(MonthArchiveView):
model = Post
date_field = 'modify_dt'
class PostDAV(DayArchiveView):
model = Post
date_field = 'modify_dt'
class PostTAV(TodayArchiveView):
model = Post
date_field = 'modify_dt'
👉 아직 제네릭 뷰가 익숙하지 않아서 PostLV, PostDV에 주석으로 라인마다 코드 설명을 해 놓았다.
ListView와 DetailView를 상속받아 해당 class를 구성하는 것으로 일반 뷰보다 편리한 기능을 제공하고 장고의 큰 장점이기도 하다.