본문 바로가기

Python_WEB/Django_Tutorial

[Django]Blog Creation Tutorial(Translation/Correction) 2

원문>

https://matthewdaly.co.uk/blog/2012/03/19/yet-another-tutorial-for-building-a-blog-using-python-and-django-part-2/

 

Yet Another Tutorial for Building a Blog Using Python and Django – Part 2 - Matthew Daly's Blog

19th March 2012 3:18 pm Yet Another Tutorial for Building a Blog Using Python and Django – Part 2 In the first part of this tutorial, we got the core elements of our blogging application working - we set up our model for posts, and a view, template and U

matthewdaly.co.uk

 

번역 / 수정>

메인 화면에 블로그 포스트 내용은 5개만 보이게 하고 페이지를 나눈다.

포스트 내용이 10개라고 했을 때

첫번째 페이지의 주소는 아래와 같고

http://www.example.com/1/

두번째 페이지의 주소는 아래와 같다.

http://www.example.com/2/

이러면 끝에 숫자가 없는 URL에 하나씩, 끝에 숫자가 있는 URL에 하나씩, 그리고 선택적인 슬래시(옵션)가 필요하다.

그리고 나서 슬러그를 추가 해서 게시물의 URL을 보기 좋고 읽기 쉽게 지정 할것이다.

 

1. urls(blogengine > urls.py)

원문 코드>

from django.urls import path

from . import views

urlpatterns = [
    url(r'^$', 'blogengine.views.getPosts'),
    url(r'^(?P<selected_page>\d+)/?$', 'blogengine.views.getPosts'),
]

 

수정 코드>

from django.urls import path

from . import views

urlpatterns = [
    path('', views.getPosts),
    path('<int:selected_page>/', views.getPosts),
]
getRecenenosts를 getPosts로 변경 한다.

 

2. views(blogengine > views.py)

원문 코드>

from django.shortcuts import render_to_response
from django.core.paginator import Paginator

from blogengine.models import Post


def getPosts(request, selected_page=1):
    # Get all blog posts
    posts = Post.objects.all().order_by('-pub_date')
    # Add pagination
    pages = Paginator(posts, 5)
    returned_page = pages.page(selected_page)
    # Display all the posts
    return render_to_response('posts.html', {'posts':returned_page.object_list})

 

수정 코드>

from django.shortcuts import render
from django.core.paginator import Paginator

from blogengine.models import Post


def getPosts(request, selected_page=1):
    # Get all blog posts
    posts = Post.objects.all().order_by('-pub_date')
    # Add pagination
    pages = Paginator(posts, 5)
    returned_page = pages.page(selected_page)
    # Display all the posts
    return render(request, 'posts.html', {'posts': returned_page.object_list})
from django.core.paginator import paginator
페이지 지정을 만드는 데 매우 유용
def getPosts(request, selected_page=1):
매개 변수의 기본 값을 지정한다. 
pages = Paginator(posts, 5)
한 페이지에 5개씩 글을 보여준다.

 

3. models(blogengine > models.py)

원문 코드>

from django.db import models


class Post(models.Model):
    title = models.CharField(max_length=200)
    pub_date = models.DateTimeField()
    text = models.TextField()
    slug = models.SlugField(max_length=40, unique=True)
    
    def __unicode__(self):
        return self.title

 

수정 코드>

from django.db import models


class Post(models.Model):
    title = models.CharField(max_length=200)
    pub_date = models.DateTimeField()
    text = models.TextField()
    slug = models.SlugField(max_length=40, unique=True, allow_unicode=True)

    def __str__(self):                              
        return self.title
slug = models.SlugField(max_length=40, unique=True, allow_unicode=True, null=False)
최대길이는 40자이고 한글이 들어올 수 있으므로 allow_unicode를 True로 준다. 그러면 한글 입력이 가능하다.

 

4. admin(blogengine > admin.py)

원문 코드>

import models

from django.contrib import admin


class PostAdmin(admin.ModelAdmin):
    prepopulated_fields = {"slug": ("title",)}
    
admin.site.register(models.Post, PostAdmin)

 

수정 코드>

from django.contrib import admin

from .models import Post


class PostAdmin(admin.ModelAdmin):
    prepopulated_fields = {"slug": ("title",)}


admin.site.register(Post, PostAdmin)
ModelAdmin에서 상속된 PostAdmin을 만들고 제목을 가져와서 슬러그 필드를 채웁니다.
제목에 공백과 다른 글자들을 제거하고 중간 중간에 -를 넣고 소문자로 변환한다.
(ex>Hello Admin Page -> hello-admin-page)

 

5. views(blogengine > views.py(가장 아래에 추가))

원문 코드>

def getPost(request, postSlug):
    # Get specified post
    post = Post.objects.filter(slug=postSlug)
    # Display specified post
    return render_to_response('posts.html', { 'posts':post})

 

수정 코드>

def getPost(request, postSlug):
    # Get specified post
    post = Post.objects.filter(slug=postSlug)
    # Display specified post
    return render(request, 'posts.html', {'posts': post})
요청된 게체와 게시물에 사용될 슬러그를 받는다.

 

6. urls(blogengine > urls.py)

원문 코드>

from django.urls import path

from . import views

urlpatterns = [
    url(r'^$', 'blogengine.views.getPosts'),
    url(r'^(?P<selected_page>\d+)/?$', 'blogengine.views.getPosts'),
    url(r'^(?P<postSlug>[-a-zA-Z0-9]+)/?$', 'blogengine.views.getPost'),
]

 

수정 코드>

from django.urls import path

from . import views


appname = 'blogengine'

urlpatterns = [
    path('', views.getPosts),
    path('<int:selected_page>/', views.getPosts),
    path('<str:postSlug>/', views.getPost),
]
제목이 한글이면 슬러그 처리시 오류가 발생 하므로 str을 줘서 강제 형변환을 준다.

 

7. posts.html

원문 코드>

<html>
    <head>
        <title>My Django Blog</title>
    </head>
    <body>
        {% for post in posts %}
        <h1><a href="/{{ post.slug }}">{{ post.title }}</a></h1>
        <h3>{{ post.pub_date }}</h3>
        {{ post.text }}
        {% endfor %}
    </body>
</html>

 

수정 코드>

<html>

    <head>
        <title>My Django Blog</title>
    </head>
    
    <body>
        {% for post in posts %}
        <h1><a href="/blog/{{ post.slug }}">{{ post.title }}</a></h1>
        <h3>{{ post.pub_date }}</h3>
        {{ post.text }}
        {% endfor %}
    </body>
    
</html>

 

8. makemigrations

python manage.py makemigrations

 

9. migrate

python manage.py migrate

 

10. 로컬 서버 실행

python manage.py runserver

 

11. views(blogengine > views.py)

원문 코드>

from django.shortcuts import render_to_response
from django.core.paginator import Paginator, EmptyPage

from blogengine.models import Post


def getPosts(request, selected_page=1):
    # Get all blog posts
    posts = Post.objects.all().order_by('-pub_date')
    # Add pagination
    pages = Paginator(posts, 5)
    # Get the specified page
    try:
        returned_page = pages.page(selected_page)
    except EmptyPage:
        returned_page = pages.page(pages.num_pages)
    # Display all the posts
    return render_to_response('posts.html', { 'posts':returned_page.object_list})
    
    
def getPost(request, postSlug):
    # Get specified post
    post = Post.objects.filter(slug=postSlug)
    # Display specified post
    return render_to_response('posts.html', { 'posts':post})

 

수정 코드>

from django.shortcuts import render
from django.core.paginator import Paginator, EmptyPage

from blogengine.models import Post


def getPosts(request, selected_page=1):
    # Get all blog posts
    posts = Post.objects.all().order_by('-pub_date')
    # Add pagination
    pages = Paginator(posts, 5)
    # Get the specified page
    try:
        returned_page = pages.page(selected_page)
    except EmptyPage:
        returned_page = pages.page(pages.num_pages)
    # Display all the posts
    return render(request, 'posts.html', {'posts': returned_page.object_list})


def getPost(request, postSlug):
    # Get specified post
    post = Post.objects.filter(slug=postSlug)
    # Display specified post
    return render(request, 'posts.html', {'posts': post})
EmptyPage
EmptyPage 예외가 발생하면 가장 높은 번호의 페이지를 반환한다.
pages.null_pages
총 페이지 수(마지막으로 페이지 번호)
null_pages
첫번째 페이지로 기본값으로 변경 가능하다.

 

추가 원문 코드>

from django.shortcuts import render_to_response
from django.core.paginator import Paginator, EmptyPage

from blogengine.models import Post


def getPosts(request, selected_page=1):
    # Get all blog posts
    posts = Post.objects.all().order_by('-pub_date')
    # Add pagination
    pages = Paginator(posts, 5)
    # Get the specified page
    try:
        returned_page = pages.page(selected_page)
    except EmptyPage:
        returned_page = pages.page(pages.num_pages)
    # Display all the posts
    return render_to_response('posts.html', { 'posts':returned_page.object_list, 'page':returned_page})
    
    
def getPost(request, postSlug):
    # Get specified post
    post = Post.objects.filter(slug=postSlug)
    # Display specified post
    return render_to_response('posts.html', { 'posts':post})

 

추가 수정 코드>

from django.shortcuts import render
from django.core.paginator import Paginator, EmptyPage

from blogengine.models import Post


def getPosts(request, selected_page=1):
    # Get all blog posts
    posts = Post.objects.all().order_by('-pub_date')
    # Add pagination
    pages = Paginator(posts, 5)
    # Get the specified page
    try:
        returned_page = pages.page(selected_page)
    except EmptyPage:
        returned_page = pages.page(pages.num_pages)
    # Display all the posts
    return render(request, 'posts.html', {'posts': returned_page.object_list, 'page': returned_page})


def getPost(request, postSlug):
    # Get specified post
    post = Post.objects.filter(slug=postSlug)
    # Display specified post
    return render(request, 'posts.html', {'posts': post})
'page':returned_page
기존 게시물 외에도 페이지 단위로 반환된 페이지를 준다.

 

12. posts.html

원문 코드>

<html>
    <head>
        <title>My Django Blog</title>
    </head>
    <body>
        {% for post in posts %}
        <h1><a href="/{{ post.slug }}">{{ post.title }}</a></h1>
        <h3>{{ post.pub_date }}</h3>
        {{ post.text }}
        {% endfor %}
        <br />
        {% if page.has_previous %}
        <a href="/{{ page.previous_page_number }}/">Previous Page</a>
        {% endif %}
        {% if page.has_next %}
        <a href="/{{ page.next_page_number }}/">Next Page</a>
        {% endif %}
    </body>
</html>

 

수정 코드>

<html>

<head>
  <title>My Django Blog</title>
</head>

<body>
  {% for post in posts %}
  <h1><a href="/blog/{{ post.slug }}">{{ post.title }}</a></h1>
  <h3>{{ post.pub_date }}</h3>
  {{ post.text }} {% endfor %}
  <br />
  {% if page.has_previous %}
  <a href="/blog/{{ page.previous_page_number }}/">Previous Page</a>
  {% endif %} {% if page.has_next %}
  <a href="/blog/{{ page.next_page_number }}/">Next Page</a>
  {% endif %}
</body>

</html>
지정된 페이지에 이전 페이지가 있으면 해당 페이지에 대한 링크를 표시
다음 페이지가 있으면 해당 페이지에 대한 링크를 표시
page.previous_page_number / page.next_page_number
해당 페이지에 대한 번호를 표시

 

13. 테스트 화면

- 관리자 페이지에서 제목 입력시 자동으로 slug 입력 확인(영문)

 

- 관리자 페이지에서 제목 입력시 자동으로 slug 입력 확인(한글)

 

- 글 내용이 5개가 안될 시 페이지 이동 안보임

 

- 글 내용이 5개 이상시 다음 페이지 표시

 

- 글 내용이 5개 이상시 이전 페이지 표시

 

- 영문 slug 처리

 

- 한글 slug 처리