본문 바로가기
파이썬 웹 서비스 만들기

7. 컨텐츠 포스팅 및 관리기능 - 7.2. 컨텐츠(글) 수정기능

by 영바이트 2020. 11. 11.

블로그에 포스팅한 글, SNS에 쓴 글 등은 수정하거나 삭제할 필요가 생긴다. 지난 포스팅(7.1)에서 글 쓰기 기능을 다루었으니 이번 포스팅에서는 글을 수정하거나 삭제할 수 있는 기능을 만들어보자.

 


7.2.1. 컨텐츠 수정

 

먼저 글을 수정하는 과정을 생각하고 정리해보자.

 

DB에서 글을 읽어온다.

읽어온 글을 페이지에 수정 가능한 형태로 보여준다.

수정된 글을 다시 DB에 저장한다.

 

웹 서비스로 구현하기 위해 위 과정을 모델/폼-뷰-로직(MVC 또는 MVL) 형태로 재구성 해보자.

 

● 모델/폼: DB에서 글을 읽어올 때 데이터의 틀인 모델이 필요하고, 페이지를 통해 수정된 내용을 입력받을 때 입력 틀인 폼이 필요하다. 하지만 수정의 대상은 저장되어 있는 글이다. 따라서 글을 생성할 때 정의했었던 모델과 폼을 그대로 적용하면 된다.

 

● 뷰: 포스팅에서 수정의 대상은 제목, 본문 등이다. 글 쓴 사람, 생성 시간 등은 기존의 데이터에서 변화가 없고, 더 추가되는 요소들도 없다. 따라서 글 쓰기 페이지를 다시 활용할 수 있다.

 

● 로직: '글 수정하기' 링크를 클릭하면 서버의 DB에서 글을 찾아서 가져오고 그 내용을 수정하기 페이지를 통해 보여준다. 그리고 사용자가 수정을 마치고 '수정하기' 버튼을 클릭하면 입력받은 내용을 다시 DB에 저장한다. 이 두 가지 기능을 수행할 로직을 새로 만들어야 한다.

 

이제 MVL 세 요소들을 실제 코드로 만들어 컨텐츠 수정 기능을 구현해보자.

 


기존의 05_posting 프로젝트를 그대로 이용하고 컨텐츠 수정 기능을 새로 추가할 것이다.

 

● 모델/폼

post 패키지의 폼 클래스(appmain/post/forms.py), 모델 클래스(appmain/post/models.py)를 그대로 사용하면 된다.

 

<폼/모델 - 기존 그대로 사용한다>

 

● 뷰

기존 글을 수정할 페이지는 글 쓰기 페이지(appmain/templates/create_post.html)를 다시 활용할 수 있다. 글 수정하기/삭제하기 버튼이 있는 글 관리 페이지가 필요하다. 글 제목을 클릭하면 글 관리 페이지로 이동할 수 있게끔 글 제목을 링크로 바꾸어 주자.

 

<컨텐츠 관리를 위한 뷰 파일들>

 

글 제목을 글 관리 페이지로 이동할 수 있는 링크로 바꾸기. 글은 서비스의 메인 페이지에 게시되므로 home.html 파일을 수정한다.

▶ appmain/templates/home.html

{%extends "layout.html"%}
{%block content%}
    {%for post in posts%}
    
    	<!-- 하이퍼링크로 수정된 글 제목 -->
        <h1><a href="/post/{{post.id}}">{{post.title}}</a></h1>
        <!-- -->
        
        <p>{{post.content}}</p>
        <p>By {{post.author}} on {{post.datePosted}}</p>
    {%endfor%}
{%endblock content%}

 

글 관리 페이지를 아래와 같이 구현하자.

▶ appmain/templates/post.html

{% extends "layout.html" %}
{% block content %}
<div>
    <p>{{post.title}}</p>
    <p>{{post.content}}</p>
    <p>{{post.date_posted}}</p>
    
    <!-- 로그인한 사용자가 글의 저자와 같을 때만 '수정하기' 링크를 보여준다. -->
    {%if current_user.is_authenticated%}
        {%if current_user.username == post.author%}
            <div>
                <a href="/post/{{post.id}}/update">Update Post</a>
            </div>
        {%endif%}
    {%endif%}
</div>
{% endblock content %}

 

글 관리 페이지에서는 글의 내용을 보여주고 수정할 수 있는 'Update Post' 링크를 제공한다. 이 Update Post 링크는 로그인한 사용자가 글을 작성한 사람과 같은 경우에만 보여준다.

 

● 로직

 

글 수정하기 작업을 정리해보면 아래와 같은 과정으로 진행된다.

 

글의 제목을 클릭했을 때 글 관리 페이지(post.html)를 보여준다.

글 관리 페이지에서 사용자가 '수정하기' 버튼을 클릭하면 글을 수정할 수 있는 뷰(create_post.html를 다시 활용한다)를 보여준다.

글 수정을 마치고 '제출하기' 버튼을 클릭하면 그 내용을 DB에 저장하도록 구현한다.

 

 

컨텐츠 관리와 관련된 내용이므로 post 패키지의 페이지 처리 로직(appmain/post/routes.py)에 필요한 로직을 코딩하자.

 

<컨텐츠 관리를 위한 로직파일>

 

▶ appmain/post/routes.py

from flask import render_template, url_for, redirect, request, abort, Blueprint
from flask_login import current_user, login_required
from appmain import db
from appmain.post.forms import PostForm
from appmain.post.models import Post

post = Blueprint('post', __name__)

@post.route("/post/new", methods=['GET', 'POST'])
@login_required
def newPost():
        ...

#### 글 제목 링크를 클릭하면 글 관리 페이지를 보여준다.
#### 제목 링크에 글의 ID(postId)를 포함하도록 만들어서 이 ID를 이용해서 DB에서 글을 가져온다.
@post.route("/post/<int:postId>")
def displayPost(postId):
    content = Post.query.get_or_404(postId)
    return render_template('post.html', title = content.title, post = content)

#### 글 관리 페이지에서 수정하기(update) 링크를 클릭하면 수정 페이지를 보여준다.
@post.route("/post/<int:postId>/update", methods=['GET', 'POST'])
####글 관리 페이지로 접근하기 전에 먼저 로그인되어 있는지 확인한다.
@login_required
def updatePost(postId):
    #### 글을 가져온다. 글이 없다면 '페이지 없음(404)'오류를 발생시킨다.
    content = Post.query.get_or_404(postId)
    #### 글 저자와 로그인한 사용자가 다르다면 '권한없음(403) 오류를 발생시킨다'
    if content.author != current_user.username:
        abort(403)
    form = PostForm()
    
    #### 사용자가 '제출' 버튼(링크)을 클릭한 경우    
    if form.validate_on_submit():
        content.title = form.title.data
        content.content = form.content.data
        db.session.commit()
        print("A post is updated: ", content.title)
        return redirect(url_for('main.home'))
    
    #### '제출' 버튼(링크)이 클릭된 경우가 아니면 수정 페이지를 준비한다.
    elif request.method == 'GET':
        #### 이전에 썼던 글의 제목과 본문을 폼의 제목과 본문에 넣어 보여준다.
        form.title.data = content.title
        form.content.data = content.content
        
    #### 글 수정 페이지를 보여준다.
    return render_template('create_post.html', title='Update Post', form=form)

 

글에서는 모델/폼 - 뷰 - 로직 순서로 막힘없이 진행(서술)했지만 실제 실습을 해보면 아직 익숙하지 않은 부분들이 많아서 천천히 진행하게 될 것이다. 위 코드들을 참고해서 연습을 거듭하다보면 점점 더 익숙해져서 개발 속도도 빨라질것이다.

 


 

이제 프로젝트를 저장하고 구현한 글 수정하기 기능을 점검해보자.

 

프로제트를 실행시키고(프로젝트의 run.py 파일을 실행) 웹 브라우저로 127.0.0.1:5000 주소로 접근한다. 아래 그림은 글을 포스팅한 사용자로 로그인한 후 홈 페이지 화면이다.

 

수정 전 포스팅

 

글 제목을 클릭하면 아래 그림과 같이 글을 관리할 수 있는 페이지로 이동된다.

 

글 관리 페이지

 

글 수정하기(Update Post) 링크를 클릭해서 글을 수정할 수 있는 페이지로 이동하자. 아래와 같이 글 내용을 한 번 수정해보자.

 

글 수정 페이지

 

수정하기(Post) 버튼을 클릭하면 웹 서비스의 메인(홈) 페이지로 이동할 것이다. 글이 정상적으로 수정되었음을 확인해 볼 수 있다.

 

수정된 글

 

참고로 윈도우 커맨드 윈도우를 통해 DB에 접속해보면 내용이 수정되어 있음을 확인해 볼 수 있다.

 

수정된 DB의 내용

 

 

댓글