● 구조
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
blog/
├── app.py
├── templates/
│ └── home.html
│ └── post.html
│ └── add_post.html
│ └── edit_post.html
├── requirements.txt
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
● 파일
(파일) requirements.txt
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
Flask
Flask-SQLAlchemy
pytz
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
(파일) app.py
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
from flask import Flask, request, redirect, url_for, render_template
from flask_sqlalchemy import SQLAlchemy
# datetime, pytz 날짜/시간 모듈 패키지 불러오기
from datetime import datetime
import pytz
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///blog.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
# 한국 시간 반환 함수
def get_kst_time():
utc_now = datetime.utcnow()
kst_timezone = pytz.timezone('Asia/Seoul')
kst_time = utc_now.replace(tzinfo=pytz.utc).astimezone(kst_timezone)
return kst_time
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
content = db.Column(db.Text, nullable=False)
date_posted = db.Column(db.DateTime, default=get_kst_time)
def __repr__(self):
return f'<Post {self.name}>'
with app.app_context():
db.create_all()
@app.route('/')
def home():
# 시간 순서대로 정렬하여 불러오기
posts = Post.query.order_by(Post.date_posted.desc()).all()
return render_template('home.html', posts=posts)
# 각 게시물 별 페이지 불러오기
@app.route('/post/<int:post_id>')
def post(post_id):
# 존재하지 않을 경우 404 ERROR
post = Post.query.get_or_404(post_id)
return render_template('post.html', post=post)
@app.route('/add', methods=['GET', 'POST'])
def add_post():
if request.method == 'POST':
title = request.form['title']
content = request.form['content']
new_post = Post(title=title, content=content, date_posted=get_kst_time())
db.session.add(new_post)
db.session.commit()
return redirect(url_for('home'))
return render_template('add_post.html')
@app.route('/edit/<int:post_id>', methods=['GET', 'POST'])
def edit_post(post_id):
post = Post.query.get_or_404(post_id)
if request.method == 'POST':
# 기존 게시물에 브라우저로부터 전송된 form의 값 덮어쓰기
post.title = request.form['title']
post.content = request.form['content']
post.date_posted = get_kst_time()
db.session.commit()
return redirect(url_for('home'))
return render_template('edit_post.html', post=post)
@app.route('/delete/<int:post_id>')
def delete_post(post_id):
post = Post.query.get_or_404(post_id)
if post:
db.session.delete(post)
db.session.commit()
return redirect(url_for('home'))
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=1999)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
(파일) home.html
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blog</title>
</head>
<body>
<h1>HOME</h1>
<a href="{{ url_for('add_post') }}">Add New Post</a>
<ul>
{% for post in posts %}
<li>
# 게시물 제목 클릭하여 각 게시물 접속
<h2><a href="{{ url_for('post', post_id=post.id) }}">{{ post.title }}</a></h2>
<p>{{ post.date_posted.strftime('%Y-%m-%d %H:%M:%S') }}</p>
<a href="{{ url_for('edit_post', post_id=post.id) }}">Edit</a>
<a href="{{ url_for('delete_post', post_id=post.id) }}">Delete</a>
</li>
{% endfor %}
</ul>
</body>
</html>
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
(파일) post.html
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blog</title>
</head>
<body>
<header>
<h1>{{ post.title }}</h1>
</header>
<div class="container">
<p>{{ post.date_posted.strftime('%Y-%m-%d %H:%M:%S') }}</p>
<div>{{ post.content }}</div>
<a href="{{ url_for('home') }}">Back to Home</a>
</div>
</body>
</html>
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
(파일) add_post.html
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blog</title>
</head>
<body>
<h1>Add New Post</h1>
<form method="POST" action="{{ url_for('add_post') }}">
<label for="title">Title:</label>
<input type="text" id="title" name="title">
<label for="content">Content:</label>
<textarea id="content" name="content"></textarea>
<button type="submit">Add Post</button>
</form>
<a href="{{ url_for('home') }}">Back to Home</a>
</body>
</html>
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
(파일) edit_post.html
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blog</title>
</head>
<body>
<h1>Edit Post</h1>
<form method="POST" action="{{ url_for('edit_post', post_id=post.id) }}">
<label for="title">Title:</label>
<input type="text" id="title" name="title" value="{{ post.title }}">
<label for="content">Content:</label>
<textarea id="content" name="content">{{ post.content }}</textarea>
<button type="submit">Save Changes</button>
</form>
<a href="{{ url_for('home') }}">Back to Home</a>
</body>
</html>
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
● 실행
Step1. 선수 작업 진행
[참고] https://uyijune15.tistory.com/222
[정리] 선수 작업
1) python3 설치# yum install -y python3 2) 최신 패키지 업데이트# yum -y update# pip install --upgrade pip 3) 필요 패키지 설치# yum -y install gcc# pip3 install gunicorn
uyijune15.tistory.com
Step2. 방화벽 설정
# firewalll-cmd --permanent --add-port=1999/tcp
# firewall-cmd --reload
Step3. 작업 디렉토리 이동
# cd blog
Step4. 필수 패키지 설치
# pip3 install -r requirements.txt
Step5. 실행
# gunicorn -w 4 -b 0.0.0.0:1999 app:app
# python app.py
● 테스트
(브라우저) http://<-IP->:<-PORT->
'여러가지 > 테스트' 카테고리의 다른 글
[프로젝트] 접근 제어 - 웹 브라우저 (0) | 2024.06.17 |
---|---|
[프로젝트] 접근 제어 - 스크립트 (0) | 2024.06.17 |
[참고] sqlite3 데이터베이스 (0) | 2024.06.15 |
[실습] Address Book - delete 기능 추가 (0) | 2024.06.15 |
[실습] Address Book (0) | 2024.06.15 |