파이썬(Python)/블로그 만들기(python,flask,mongo)

블로그만들기(2) - 게시판 작성한 글 확인하기(파이썬)

끄적끄적아무거나 2021. 2. 3. 17:07
반응형

블로그만들기(1)에서 게시판 글쓰는 환경을 구축하였다. 이제 글쓰면 바로 글 내용을 확인할 수있는 게시판 읽기 기능을 만들 것이다.

 

동작원리는 아래와 같다.

 

1. 게시물 쓰기가 완료 되면 해당 게시물을 읽는 페이지로  HTTP GET 요청을 보낸다.

2. 요청과 함께 db 인덱스 번호인 _id 값을 GET 신호와 같이 보낸다.

3. _id 값으로 db에 접근해서 읽고 html로 출력해준다. 

 

 


 

코드 - bulletin_wr.html >>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>bulletin_write</title>
    <body>
        <table>
            <form name="form" method="POST" action="/bulletin_wr">
                <tbody>
                    <tr>
                        <td>Title</td>
                        <td><input type="text" name="title"></td>
                    </tr>
                    <tr>
                        <td>Content</td>
                        <td><textarea name="contents"></textarea></td>
                    </tr>
                    <tr>
                        <td><input type="submit"></td>
                    </tr>
                </tbody>
            </form>
        </table>
    </body>
</html>

주석>>

1장 코드와 동일함, 단순히 글을 쓸 수 있게 구성한 html 임

 

 

코드 - bulletin_rd.html >>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>bulletin_read</title>
</head>
<body>
    {{db_data.title}}
    <br>
    {{db_data.pubdate}}
    <br>
    {{db_data.contents}}
    <br>
</body>
</html>

주석>>

bulletin_rd 주소로 HTTP GET 요청을 받으면 flask를 통해 db_data를 전달 받고 받은 값을 html로 보여준다.

 

 

코드 - board_01.py

from flask import *
from flask_pymongo import PyMongo
from bson.objectid import ObjectId
import time

#########################################################
# Flask 선언, mongodb와 연결
web_bulletin = Flask(__name__, template_folder="templates")
web_bulletin.config["MONGO_URI"] = "mongodb://localhost:27017/bulletin" 
web_bulletin.config['SECRET_KEY'] = 'psswrd'

mongo = PyMongo(web_bulletin)
#########################################################

@web_bulletin.route("/bulletin_wr", methods=["GET", "POST"])
def bulletin_write():
    if request.method == "POST":
        cur_time = time.strftime("%y%m%d_%H%M%S")
        title = request.form.get("title")
        contents = request.form.get("contents")

        bulletin = mongo.db.bulletin

        to_db = {
            "title": title,
            "contents": contents,
            "view_cnt": 0,
            "pubdate": cur_time,
        }
        to_db_post = bulletin.insert_one(to_db)
        print("to_db_post :",to_db_post)

        return redirect(url_for("bulletin_rd", idx = to_db_post.inserted_id))
    else:
        return render_template("bulletin_wr.html")

@web_bulletin.route("/bulletin_rd")
def bulletin_rd():
    print("arg :", request.args.get("idx"))
    if request.args.get("idx") :
        idx = request.args.get("idx")
        bulletin = mongo.db.bulletin
        print("idx :", type(idx))
        print("ObjectId(idx) :", type(ObjectId(idx)))
        print(bulletin.find_one({"_id": ObjectId(idx)}))
        if bulletin.find_one({"_id": ObjectId(idx)}):
            bulletin_data = bulletin.find_one({"_id": ObjectId(idx)})
            #db에서 찾을때 _id 값은 string이 아닌 ObjectId로 바꿔야함
            print(bulletin_data)
            if bulletin_data != "":
                db_data = {
                    "id": bulletin_data.get("_id"),
                    "title": bulletin_data.get("title"),
                    "contents": bulletin_data.get("contents"),
                    "pubdate": bulletin_data.get("pubdate")
                }

                return render_template("bulletin_rd.html", db_data = db_data)
        return abort(404)
    return abort(404)


if __name__ == "__main__":
    web_bulletin.run(host='0.0.0.0', debug=True, port=9999)


 

주석>>

def bulletin_write(): 부분은 "블로그만들기(1)" 에서 봤던 부분한 한부분 빼고 유사하다. 변경 된 부분은 글 작성 완료 후 redirect 로 bulletin_rd.html로 연결해준다. 이때 url_for를 사용하면 주소값을 텍스트로 받아 준다. 그리고 주소값에 ? 로 연결 해서 argument를 넣는 것처럼 url_for 괄호 안에 넣고 싶은 변수 값을 넣으면 해당 값이 arguement 들어가는 방식으로 주소값을 받을 수 있다. 그리고 bulletin_rd.html로 연결하게 되는 것이다. 

 

여기서 redirect 과 render_template 차이를 간략하게 설명하자면 redirect 는 아예 해당 페이지에 다시 재접속을 하게 되는 것이다. render_template 는 현재 내가 그 페이지에 머물고 있다면 페이지를 render(변경)해주는 것이다. 페이지에 요청이 들어가는 것이 아닌 flask에서 html로 값만 전달해줘서 html에 변경하는 것이다. 

 

def bulletin_rd(): 은 arguement 로 idx 값을 받았다 그 값으로 db에서 내용을 불러와야한다. 이때 id는 string으로 쓰면 되는 것이 아니고 ObjectId 로 타입을 변경해야 db에서 처리할 수 있다. 

 

db의 find_one 함수를 사용해서 해당 값을 불러오면 값을 db_data 변수에 dictionary 형태로 저장해서 render_template 함수를 사용해서 html에 보내주고 사용자는 결과 값을 확인할 수 있다. 

 

주의할 점>>

코드 작성 중에 아래와 같은 에러 메세지를 받았었다

 

"werkzeug.routing.BuildError: Could not build url for endpoint 'lists' with values ['data', 'page']. Did you mean 'static' instead?"

 

해당 메세지는 html 작성시 위 정보를 사용하지 않아서 <!--  -->를 사용하여 주석 처리를 하였는데도 발생한것이다. 그래서 아예 주석 처리 문구를 삭제하니 사라졌다. 다음에 코드를 작성할 때 참조하길 바란다.

 

 

결과>>

위 결과는 콘솔에 나온 결과이다.

 

아래 영상은 동작시켰을때 글작성부터 확인까지 녹화한 결과이다.

 

 

 

반응형