뼈대 만들기
블로그 앱에 대한 설정 클래스를 settings.py에 등록한다.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'bookmark.apps.BookmarkConfig',
'blog.apps.BlogConfig', # 추가
]
models.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'
ordering = ('-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()
def get_next(self):
return self.get_next_by_modify_dt()
위 코드에서 필요한 부분 몇가지만 설명 하겠다.
CharField : 한 줄로 입력된다.
Slug : 페이지나 포스트를 설명하는 핵심 단어의 집합.
SlugField : 보통 제목의 단어들을 하이픈으로 연결해 생성하며, URL에서 pk대신 사용되는 경우가 많다. pk를 사용하면 숫자로만 되어 있어 그 내용을 유추하기 어렵지만, 슬러그를 사용하면 보통의 단어들이라서 이해하기 쉽다.
TextField : 여러 줄 입력이 가능.
DateTimeField : 날짜와 시간을 입력. auto_now 속성은 시각을 자동으로 기록하게 한다.
Meta : 필드 속성 외에 필요한 파라미터가 있으면, Meta 내부 클래스로 정의한다.
admin.py 수정
앞서 정의한 테이블도 admin 사이트에 보이도록 수정한다.
from django.contrib import admin
from blog.models import Post
@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
list_display = ('id', 'title', 'modify_dt')
list_filter = ('modify_dt',)
search_fields = ('title', 'content')
prepopulated_fields = {'slug': ('title',)}
수정 했다면 반영해주자
확인해 보면 정상적으로 반영된 것을 볼 수 있다.
urls.py 수정
블로그 앱의 mysite/urls.py와 blog/urls.py 2개의 파일에 코딩하고 2장에서 작성했던 북마크앱의 url도 2개의 파일로 수정한다. 이와같이 두개의 파일을 각각 수정해 주는 것은 확장성 측면에서 유리하다.
# mysite/urls.py
from django.contrib import admin
from django.urls import path, include
# from bookmark.views import BookmarkLV, BookmarkDV
urlpatterns = [
path('admin/', admin.site.urls),
path('bookmark/', include('bookmark.urls')),
path('blog/', include('blog.urls')),
# class-based views
# path('bookmark/', BookmarkLV.as_view(), name='index'),
# path('bookmark/<int:pk>/', BookmarkDV.as_view(), name='detail'),
]
# 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 = [
path('', views.PostLV.as_view(), name='index'),
path('post/', views.PostLV.as_view(), name='post_list'),
re_path(r'^post/(?P<slug>[-\w]+)/$', views.PostDV.as_view(), name='post_detail'),
path('archive/', views.PostAV.as_view(), name='post_archive'),
path('archive/<int:year>/', views.PostYAV.as_view(), name='post_year_archive'),
path('archive/<int:year>/<str:month>/', views.PostMAV.as_view(), name='post_month_archive'),
path('archive/<int:year>/<str:month>/<int:day>/', views.PostDAV.as_view(), name='post_day_archive'),
path('archive/today/', views.PostTAV.as_view(), name='post_today_archive'),
]
views.py 수정
from django.views.generic import ListView, DetailView
from django.views.generic import ArchiveIndexView, YearArchiveView, MonthArchiveView
from django.views.generic import DayArchiveView, TodayArchiveView
from blog.models import Post
#--- ListView
class PostLV(ListView):
model = Post
template_name = 'blog/post_all.html'
context_object_name = 'posts'
paginate_by = 2
#--- DetailView
class PostDV(DetailView):
model = Post
#--- ArchiveView
class PostAV(ArchiveIndexView):
model = Post
date_field = 'modify_dt'
class PostYAV(YearArchiveView):
model = Post
date_field = 'modify_dt'
make_object_list = True
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'
제네릭 뷰의 몇가지만 설명하겠다.
ListView : 테이블로부터 객체 리스트를 가져와 그 리스트를 출력한다.
DetailView : 테이블로부터 특정 객체를 가져와 그 객체의 상세 정보를 출력한다. 여기서 특정 객체를 조회하기 위한 키는 기본 키 대신 slug 속성을 사용 하고 있다.
ArchiveIndexView : 테이블로 부터 객체 리스트를 가져와, 날짜 필드를 기준으로 최신 객체를 먼저 출력한다.
YearArchiveView : 테이블로부터 날짜 필드의 연도를 기준으로 객체 리스트를 가져와 그 객체들이 속한 월을 리스트로 출력한다.
MonthArchiveView : 테이블로부터 날짜 필드의 연월을 기준으로 객체 리스트를 가져와 그 리스트를 출력한다.
DayArchiveView : 테이블로부터 날짜 필드의 연월일을 기준으로 객체 리스트를 가져와 그 리스트를 출력한다.
TodayArchiveView : 날짜 필드가 오늘인 객체 리스트를 가져와 그 리스트를 출력한다.
Template
# post_all.html
<h1>Blog List</h1>
<br>
{% for post in posts %}
<h3><a href='{{ post.get_absolute_url }}'>{{ post.title }}</a></h3>
{{ post.modify_dt|date:"N d, Y" }}
<p>{{ post.description }}</p>
{% endfor %}
<br>
<div>
<span>
{% if page_obj.has_previous %}
<a href="?page={{ page_obj.previous_page_number }}">PreviousPage</a>
{% endif %}
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}">NextPage</a>
{% endif %}
</span>
</div>
# post_archive_day.html
<h1>Post Archives for {{ day|date:"N d, Y" }}</h1>
<div>
<ul>
{% for post in object_list %}
<li>{{ post.modify_dt|date:"Y-m-d" }}
<a href="{{ post.get_absolute_url }}"><strong>{{ post.title }}</strong></a></li>
{% endfor %}
</ul>
</div>
# post_archive_month.html
<h1>Post Archives for {{ month|date:"N, Y" }}</h1>
<div>
<ul>
{% for post in object_list %}
<li>{{ post.modify_dt|date:"Y-m-d" }}
<a href="{{ post.get_absolute_url }}"><strong>{{ post.title }}</strong></a></li>
{% endfor %}
</ul>
</div>
# post_archive_year.html
<h1>Post Archives for {{ year|date:"Y" }}</h1>
<ul>
{% for date in date_list %}
<li style="display: inline;">
<a href="{% url 'blog:post_month_archive' year|date:'Y' date|date:'b' %}">{{ date|date:"F" }}</a></li>
{% endfor %}
</ul>
<br>
<div>
<ul>
{% for post in object_list %}
<li>{{ post.modify_dt|date:"Y-m-d" }}
<a href="{{ post.get_absolute_url }}"><strong>{{ post.title }}</strong></a></li>
{% endfor %}
</ul>
</div>
# post_archive.html
<h1>Post Archives until {% now "N d, Y" %}</h1>
<ul>
{% for date in date_list %}
<li style="display: inline;">
<a href="{% url 'blog:post_year_archive' date|date:'Y' %}">Year-{{ date|date:"Y" }}</a></li>
{% endfor %}
</ul>
<br/>
<div>
<ul>
{% for post in object_list %}
<li>{{ post.modify_dt|date:"Y-m-d" }}
<a href="{{ post.get_absolute_url }}"><strong>{{ post.title }}</strong></a></li>
{% endfor %}
</ul>
</div>
# post_detail.html
<h2>{{ object.title }}</h2>
<p>
{% if object.get_previous %}
<a href="{{ object.get_previous.get_absolute_url }}" title="View previous post">
«-- {{ object.get_previous }}
</a>
{% endif %}
{% if object.get_next %}
| <a href="{{ object.get_next.get_absolute_url }}" title="View next post">
{{ object.get_next }} --»
</a>
{% endif %}
</p>
<p>{{ object.modify_dt|date:"j F Y" }}</p>
<br>
<div>
{{ object.content|linebreaks }}
</div>
'Django' 카테고리의 다른 글
[Django] Bookmark 앱, Blog 앱 개선하기 (0) | 2022.07.22 |
---|---|
[Django] 첫 페이지 만들기 (0) | 2022.07.22 |
[Django] 가상환경 설정, Bookmark 앱 개발 (0) | 2022.07.20 |
[Django] 장고 파헤쳐보기 (0) | 2022.07.20 |
[Django] What is Django? (0) | 2022.07.20 |