공부/Flask
[Flask] 간단한 게시판 만들기
래울
2021. 10. 4. 14:00
군대에서 추석연휴간 Flask 공부목적으로 간단한 게시판만들기를 했다.
회원가입, 로그인, 글작성, 글수정, 글삭제 정도..?
flask 체험느낌이라 보안, 디자인등은...ㅇㅅㅇ
디렉토리 구조
login_service : 회원가입/로그인 기능
main : index.py, 메인페이지, 보드, 게시글 관련 기능
module : mysql_db
schema : 테이블 정의 등...
static : 업로드 이미지, 그외 이미지, js, css 파일 등
templates : 페이지들 .html
index.py
#pwd : flask_tutorial/app/main/index.py
from flask import Blueprint, request, render_template, flash, redirect, url_for, session
from flask import current_app as app
from flask import Flask, request
from sqlalchemy import create_engine, text
from app.module import dbModule
from werkzeug.utils import secure_filename
import os
# 추가할 모듈이 있다면 추가
main = Blueprint('main', __name__, url_prefix='/') #index파일을 들어갔을때, 이름을 어떻게 할지, url_prefix는 url을 뒤에 어떻게 붙일지 결정
@main.route('/', methods=['GET'])
def index():
## db연결 ##
db_class = dbModule.Database() #db연결
sql = "SELECT * FROM board;"
boards = db_class.executeAll(sql) #[{},{},...,{}] 의 형태
if 'userid' not in session:
#print("비로그인 상태")
return render_template('/main/index.html', boards=boards)
#로그인시, write, delete, update 가능
#admin은 db자체 편집가능 회원정보, 게시글정보
#print("로그인 상태")
userid = session.get('userid', None)
return render_template('/main/index.html', userid=userid, boards=boards)
@main.route('/write', methods=['GET','POST'])
def write():
if 'userid' not in session:
#print("비로그인 상태")
return "<script>alert(\'로그인 후 이용하세요.\');document.location.href=\"login_service/login\"</script>"
if request.method == 'GET':
return render_template('/main/write.html')
#print("로그인 상태")
title = request.form['title']
password = request.form['password']
contents = request.form['contents']
if title=='' or password=='' or contents=='':
return "<script>alert(\'* 은 필수입력입니다.\');document.location.href=\"/write\"</script>"
#파일 업로드
titleimg = request.files['title_image']
fn = secure_filename(titleimg.filename)
if not fn: #파일이 없으면
fn = 'dummy-image.jpg'
else:
######같은 이름 파일 업로드 중복처리.
_ = 0
while os.path.isfile("app/static/img/"+fn):
fn = str(_)+fn
_ += 1
titleimg.save(os.path.join('app/static/img/'+ fn))
#print(title,password,contents,request.remote_addr,session.get('userid'))
db_class = dbModule.Database() #db연결
userid = session.get('userid')
sql = "SELECT name from user where id=%s;"
username = db_class.executeAll(sql, userid) #username 받아오기
sql = "INSERT INTO board (pwd, name, title, content, ip, viewcnt, titleimg) VALUES (%s, %s, %s, %s, %s, %s, %s);"
args = (password, username[0]['name'], title, contents, request.remote_addr, 0, fn)
#print(args)
boards = db_class.executeAll(sql, args)
db_class.commit()
return redirect('/')
@main.route('/board/<int:id>')
def board(id):
## db연결 ##
db_class = dbModule.Database() #db연결
sql = "SELECT * FROM board WHERE id=%s;"
board = db_class.executeAll(sql, id) #[{},{},...,{}] 의 형태
if 'userid' not in session:
#print("비로그인 상태")
return render_template('/main/board.html', board=board[0])
#print("로그인 상태")
userid = session.get('userid', None)
return render_template('/main/board.html', board=board[0], num=id)
## 글 수정하기
@main.route('/update', methods=['GET','POST'])
def update():
if 'userid' not in session:
#print("비로그인 상태")
return "<script>alert(\'로그인 후 이용하세요.\');document.location.href=\"login_service/login\"</script>"
#print("로그인 상태")
db_class = dbModule.Database() #db연결
bid = request.args.get('bid')
if request.method == 'GET':
if request.args.get('bid')!=None and bid!='':
sql = "SELECT * FROM board WHERE id=%s;"
old_board = db_class.executeAll(sql, bid)
return render_template('/main/update.html', old_board=old_board[0])
# POST
title = request.form['title']
contents = request.form['contents']
password = request.form['password']
if title=='' or password=='' or contents=='':
return "<script>alert(\'* 은 필수입력입니다.\');window.history.back();</script>"
sql = "SELECT pwd, titleimg FROM board WHERE id=%s;"
old_board = db_class.executeAll(sql, bid)
if old_board[0]['pwd'] != password:
return "<script>alert(\'비밀번호가 일치하지않습니다.\');window.history.back();</script>"
titleimg = request.files['title_image'] #파일 업로드, 글 수정시 이전파일 삭제 후 업로드
fn = secure_filename(titleimg.filename)
print(old_board, fn, titleimg.filename)
if old_board[0]['titleimg']!=''and old_board[0]['titleimg']!=None and old_board[0]['titleimg']!='dummy-image.jpg' and fn: #이미 파일이 있을때 업로드
os.remove('app/static/img/' + old_board[0]['titleimg'])
######같은 이름 파일 업로드 중복처리.
if fn:
_ = 0
while os.path.isfile("app/static/img/"+fn):
fn = str(_)+fn
_ += 1
titleimg.save(os.path.join('app/static/img/'+ fn))
sql = "UPDATE board SET title=%s, content=%s, titleimg=%s WHERE id=%s;"
args = (title, contents, fn, bid)
else:
sql = "UPDATE board SET title=%s, content=%s WHERE id=%s;"
args = (title, contents, bid)
boards = db_class.executeAll(sql, args)
db_class.commit()
sql = "SELECT * FROM board WHERE id=%s;"
board = db_class.executeAll(sql, bid)
return render_template('/main/board.html', board=board[0], num=bid)
#한글파일 이름깨지는 이슈 해결....ㅜㅡㅜ >> 지원안한다고함;
@main.route('/delete', methods=['GET','POST'])
def delete():
if 'userid' not in session:
#print("비로그인 상태")
return "<script>alert(\'로그인 후 이용하세요.\');document.location.href=\"login_service/login\"</script>"
#print("로그인 상태")
bid = request.args.get('bid')
if request.method == 'GET':
if request.args.get('bid')!=None and bid!='':
return render_template('/main/delete.html')
db_class = dbModule.Database() #db연결
sql = "SELECT pwd FROM board WHERE id=%s;"
pwd = db_class.executeAll(sql, bid)
#print(pwd[0]['pwd'], request.form['password'])
if pwd[0]['pwd'] == request.form['password']:
sql = "SELECT titleimg FROM board WHERE id=%s;"
img = db_class.executeAll(sql, bid)[0]['titleimg']
if img!='dummy-image.jpg' and len(img)!=0: #이미 파일이 있을때 업로드
os.remove('app/static/img/' + img)
sql = "DELETE FROM board WHERE id=%s;"
db_class.executeAll(sql, bid)
db_class.commit()
return "<script>alert(\'삭제성공\');document.location.href=\"/\"</script>"
return "<script>alert(\'비밀번호가 일치하지않습니다.\');window.history.back();</script>"
####################################### test code start
# code for test.html
@main.route('/test', methods=['GET'])
def test():
return render_template('/main/test.html')
#
#######################################
test.py(login_service)
from flask import Blueprint, request, render_template, flash, redirect, url_for, Flask, session
from flask import current_app as current_app
from app.module import dbModule
test = Blueprint('login_service', __name__, url_prefix='/login_service')
@test.route('/register', methods=['GET','POST'])
def register():
if request.method == 'GET':
if 'userid' in session:
session.clear() #로그인 페이지 진입시, 자동 로그아웃
return "<script>alert(\'회원가입을 위해 로그아웃합니다.\');document.location.href=\"register\"</script>"
return render_template('/login_service/register.html')
uid = request.form['userid']
uname = request.form['username']
upw = request.form['password']
upw2 = request.form['re_password']
#유효성 검사
if uid=='' or uname=='' or upw=='' or upw2=='': #필수입력
return "<script>alert(\'모두 입력해주세요.\');document.location.href=\"register\"</script>"
if not upw == upw2:
return "<script>alert(\'비밀번호 확인이 일치하지않습니다.\');document.location.href=\"register\"</script>"
db_class = dbModule.Database() #db연결
sql = "SELECT id FROM user WHERE id=%s;" #이미 db에 아이디가 존재하는지 검색, 아이디 중복검사
if db_class.executeAll(sql, uid): #executeAll함수는 sql과 args를 인자로 받음
return "<script>alert(\'이미 존재하는 아이디입니다.\');document.location.href=\"register\"</script>"
sql = "INSERT INTO user VALUES (%s, %s, %s);"
db_class.executeAll(sql, (uid, upw, uname))
db_class.commit() #commit이 없으면 db에 저장이안됨
return "<script>alert(\'회원가입이 완료됬습니다.\');document.location.href=\"login\"</script>" #성공적으로 가입 완료되면, 메시지띄우고, 로그인창으로 이동
# 로그인
@test.route('/login', methods=['GET','POST']) #GET과 POST메서드 모두 허용
def login():
if request.method == 'GET':
if 'userid' in session:
session.clear() #로그인 페이지 진입시, 자동 로그아웃
return "<script>alert(\'로그인페이지로 돌아갑니다.\');document.location.href=\"login\"</script>"
return render_template('/login_service/login.html')
uid = request.form['userid']
upw = request.form['password']
db_class = dbModule.Database() #db연결
sql = "SELECT pwd FROM user WHERE id=%s;" #해당 아이디의 pwd를 가져옴
row = db_class.executeAll(sql, uid)
if row and upw == row[0]['pwd']: #결과가 하나라도 존재하면, 입력한pw와 비교
session['userid'] = uid #세션에 uid를 저장
return "<script>document.location.href=\'/\';</script>" #main으로 돌아감 index.html
return "<script>alert(\'비밀번호가 일치하지않습니다.\');document.location.href=\"login\"</script>"