데이터 수정
수정 페이지 라우트 추가(main.py)
@app.route('/edit_artwork/<int:artwork_id>', methods=['GET', 'POST'])
def edit_artwork(artwork_id):
if request.method == 'POST':
title = request.form['title']
description = request.form['description']
# 이미지 파일이 제공되었는지 확인
file = request.files.get('file')
if file and file.filename != '':
filename = secure_filename(file.filename)
file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
file.save(file_path)
cursor.execute("UPDATE images SET title=%s, description=%s, file_path=%s WHERE id=%s", (title, description, file_path, artwork_id))
else:
cursor.execute("UPDATE images SET title=%s, description=%s WHERE id=%s", (title, description, artwork_id))
db.commit()
return redirect(url_for('view_artwork', artwork_id=artwork_id))
# GET 요청 처리: 기존 작품 정보를 폼에 불러옴
cursor.execute("SELECT id, title, description, file_path, created_at FROM images WHERE id = %s", (artwork_id,))
artwork = cursor.fetchone()
if artwork:
return render_template('edit_artwork.html', artwork=artwork)
else:
return "Artwork not found", 404
상세보기 페이지에 수정 버튼 추가 (view_artwork.html)
수정 페이지 템플릿 생성(edit_artwork.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Edit Artwork</title>
</head>
<body>
<h1>Edit Artwork</h1>
<form action="" method="post" enctype="multipart/form-data">
<input type="text" name="title" value="" required>
<textarea name="description" required></textarea>
<input type="file" name="file">
<input type="submit" value="Update Artwork">
</form>
<a href="/view_artwork/">Cancel</a>
</body>
</html>
데이터 삭제
상세 페이지에 삭제 버튼 추가(view_artwork.html)
<form action="/delete_artwork/" method="post">
<button type="submit">Delete Artwork</button>
</form>
삭제 라우트 추가(main.py)
@app.route('/delete_artwork/<int:artwork_id>', methods=['POST'])
def delete_artwork(artwork_id):
# 작품의 파일 경로를 조회
cursor.execute("SELECT file_path FROM images WHERE id = %s", (artwork_id,))
artwork = cursor.fetchone()
# 조회된 작품 정보가 있는 경우에만 다음 단계 진행
if artwork:
file_path = artwork[0]
# 데이터베이스에서 삭제
cursor.execute("DELETE FROM images WHERE id = %s", (artwork_id,))
db.commit()
# 파일 시스템에서 파일을 삭제
try:
os.remove(os.path.join(app.config['UPLOAD_FOLDER'], file_path.split('/')[-1]))
except OSError as e:
print(f"Error: {e.strerror} - {e.filename}")
else:
print("Artwork not found")
return redirect(url_for('listall'))
회원가입
사용자 데이터 베이스 테이블 생성
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL
);
Flask-Login 설치
pip install flask-login
Flask 애플리케이션 설정(main.py)
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user
from werkzeug.security import generate_password_hash, check_password_hash
# Flask-Login 설정
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
# 사용자 모델 정의
class User(UserMixin):
def __init__(self, id, username, password_hash):
self.id = id
self.username = username
self.password_hash = password_hash
# 사용자 로더 설정
@login_manager.user_loader
def load_user(user_id):
cursor.execute("SELECT id, username, password_hash FROM users WHERE id = %s", (user_id,))
user = cursor.fetchone()
if user:
return User(id=user[0], username=user[1], password_hash=user[2])
return None
signup라우트 구현
@app.route('/signup', methods=['GET', 'POST'])
def signup():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
# 입력 유효성 검사
if not username or not password:
flash('Username and password are required!')
return redirect(url_for('signup'))
# 비밀번호 해시 생성
password_hash = generate_password_hash(password)
# 사용자 이름 중복 검사
cursor.execute("SELECT * FROM users WHERE username = %s", (username,))
if cursor.fetchone():
flash('Username already exists.')
return redirect(url_for('signup'))
# 사용자 데이터베이스에 추가
try:
cursor.execute("INSERT INTO users (username, password_hash) VALUES (%s, %s)", (username, password_hash))
db.commit()
except mysql.connector.Error as err:
print("Something went wrong: {}".format(err))
db.rollback()
return "Signup failed"
flash('Signup successful! You can now login.', 'success')
return redirect(url_for('login'))
return render_template('signup.html')
signup 템플릿(signup.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Signup</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h2>Signup</h2>
<!-- 메시지 플래싱을 위한 영역 -->
{% with messages = get_flashed_messages() %}
{% if messages %}
{% for message in messages %}
<div class="alert alert-warning" role="alert">{{ message }}</div>
{% endfor %}
{% endif %}
{% endwith %}
<!-- 회원 가입 폼 -->
<form action="/signup" method="post">
<div class="form-group">
<label for="username">Username:</label>
<input type="text" class="form-control" id="username" name="username" placeholder="Enter username" required>
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="password" class="form-control" id="password" name="password" placeholder="Enter password" required>
</div>
<button type="submit" class="btn btn-primary">Signup</button>
</form>
<!-- 로그인 페이지로의 링크 -->
<p>Already have an account? <a href="/login">Login here</a>.</p>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.2/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>