Notice
Recent Posts
Recent Comments
Link
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
Archives
Today
Total
관리 메뉴

RUBY

[SJCU]앱개발기초 기말과제_간단한 todolist앱 만들기 본문

SJCU/앱개발기초

[SJCU]앱개발기초 기말과제_간단한 todolist앱 만들기

ruby-jieun 2024. 6. 17. 17:07


 

 

 

앱개발기초
기말과제

 


 

간단한 todolist앱 만들기

 


 

 

 

todolist.mp4
0.39MB

앱실행영상

 

 

 

 

추가를 누르면 작성창이 나옵니다.

 

내용 작성 후 추가를 누르면

 

 

 

작성 된 내용이 추가됩니다.

 

 

 

수정을 누르면 내용을 수정할 수 있습니다 완료를 선택하면 저장됩니다

 

삭제 버튼을 통해 내용을 삭제할 수 있습니다.

 

 

 

 

 

 

app.py

from flask import Flask, render_template, request, redirect, url_for
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
# 데이터베이스 설정
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///todo.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)

# Task 모델 정의
class Task(db.Model):
    id = db.Column(db.Integer, primary_key=True)  # 기본 키
    content = db.Column(db.String(200), nullable=False)  # 작업 내용
    completed = db.Column(db.Boolean, default=False)  # 완료 여부

    def __repr__(self):
        return f'<Task {self.id}>'

# 메인 페이지 라우트
@app.route('/')
def index():
    tasks = Task.query.all()  # 모든 작업 가져오기
    return render_template('index.html', tasks=tasks)  # 템플릿 렌더링

# 작업 추가 라우트
@app.route('/add', methods=['POST', 'GET'])
def add_task():
    if request.method == 'POST':
        task_content = request.form['content']
        new_task = Task(content=task_content)  # 새 작업 생성

        try:
            db.session.add(new_task)  # 작업 추가
            db.session.commit()  # 변경 사항 커밋
            return redirect('/')  # 메인 페이지로 리다이렉트
        except:
            return '작업 추가 중 문제가 발생했습니다.'  # 오류 메시지 반환
    else:
        return render_template('add_task.html')  # 작업 추가 템플릿 렌더링

# 작업 수정 라우트
@app.route('/update/<int:id>', methods=['GET', 'POST'])
def update_task(id):
    task = Task.query.get_or_404(id)  # 작업 가져오기

    if request.method == 'POST':
        task.content = request.form['content']
        task.completed = 'completed' in request.form

        try:
            db.session.commit()  # 변경 사항 커밋
            return redirect('/')  # 메인 페이지로 리다이렉트
        except:
            return '작업 업데이트 중 문제가 발생했습니다.'  # 오류 메시지 반환
    else:
        return render_template('update_task.html', task=task)  # 작업 수정 템플릿 렌더링

# 작업 삭제 라우트
@app.route('/delete/<int:id>')
def delete_task(id):
    task = Task.query.get_or_404(id)  # 작업 가져오기

    try:
        db.session.delete(task)  # 작업 삭제
        db.session.commit()  # 변경 사항 커밋
        return redirect('/')  # 메인 페이지로 리다이렉트
    except:
        return '작업 삭제 중 문제가 발생했습니다.'  # 오류 메시지 반환

# 애플리케이션 실행
if __name__ == "__main__":
    with app.app_context():
        db.create_all()
        print("데이터베이스 테이블이 생성되었습니다.")
    app.run(debug=True)

 

 

 

 

 

index.html

<!DOCTYPE html>
<html>
<head>
    <title>할 일 목록</title>
    <!-- 부트스트랩 CSS 추가 -->
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
    <!-- 커스텀 CSS 추가 -->
    <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
    <div class="container">
        <!-- 페이지 상단의 큰 배경과 제목 -->
        <div class="jumbotron my-4">
            <h1 class="display-4">할 일 목록</h1>
            <p class="lead">나의 TO DO LIST 관리하기</p>
            <!-- 작업 추가 버튼 -->
            <a href="/add" class="btn btn-secondary btn-lg">추가</a>
        </div>
        <!-- 할 일 목록 리스트 -->
        <ul class="list-group">
            {% for task in tasks %}
            <li class="list-group-item d-flex justify-content-between align-items-center">
                {{ task.content }}
                <div>
                    <!-- 수정 버튼 -->
                    <a href="/update/{{ task.id }}" class="btn btn-primary btn-sm mr-2">수정</a>
                    <!-- 삭제 버튼 -->
                    <a href="/delete/{{ task.id }}" class="btn btn-danger btn-sm">삭제</a>
                </div>
            </li>
            {% endfor %}
        </ul>
    </div>
</body>
</html>

 

 

 

 

 

add_task.html

<!DOCTYPE html>
<html>
<head>
    <title>작업 추가</title>
    <!-- 부트스트랩 CSS 추가 -->
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container">
        <!-- 카드 형식의 박스 생성 -->
        <div class="card my-4">
            <div class="card-body">
                <h1 class="card-title">TO DO LIST 추가하기</h1>
                <!-- 폼 시작 -->
                <form method="POST">
                    <div class="form-group">
                        <!-- 입력 필드 레이블 -->
                        <label for="content">작성 내용:</label>
                        <!-- 내용 입력 필드 -->
                        <input type="text" id="content" name="content" class="form-control" required>
                    </div>
                    <!-- 제출 버튼 -->
                    <input type="submit" value="추가" class="btn btn-secondary">
                </form>
                <!-- 뒤로가기 버튼 -->
                <a href="/" class="btn btn-link mt-3">뒤로</a>
            </div>
        </div>
    </div>
</body>
</html>

 

 

 

update_task.html

<!DOCTYPE html>
<html>
<head>
    <title>작업 수정</title>
    <!-- 부트스트랩 CSS 추가 -->
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container">
        <!-- 카드 형식의 박스 생성 -->
        <div class="card my-4">
            <div class="card-body">
                <h1 class="card-title">작업 수정</h1>
                <!-- 폼 시작 -->
                <form method="POST">
                    <div class="form-group">
                        <!-- 작업 내용 레이블 -->
                        <label for="content">작업:</label>
                        <!-- 작업 내용 입력 필드 -->
                        <input type="text" id="content" name="content" class="form-control" value="{{ task.content }}" required>
                    </div>
                    <div class="form-check mb-3">
                        <!-- 완료 여부 체크박스 -->
                        <input type="checkbox" id="completed" name="completed" class="form-check-input" {% if task.completed %}checked{% endif %}>
                        <label for="completed" class="form-check-label">완료</label>
                    </div>
                    <!-- 작업 수정 버튼 -->
                    <input type="submit" value="작업 수정" class="btn btn-secondary">
                </form>
                <!-- 뒤로가기 버튼 -->
                <a href="/" class="btn btn-link mt-3">뒤로</a>
            </div>
        </div>
    </div>
</body>
</html>

 

 

 

style.css

/* 기본 스타일 설정 */
body {
    font-family: Arial, sans-serif; /* 기본 글꼴 설정 */
    background-color: #f8f9fa; /* 배경색 설정 */
    margin: 0; /* 기본 여백 제거 */
    padding: 0; /* 기본 패딩 제거 */
}

/* 큰 배경과 제목 설정 */
.jumbotron {
    background-color: #343a40; /* 배경색 설정 */
    color: #fff; /* 텍스트 색상 설정 */
}

/* 카드 스타일 설정 */
.card {
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* 그림자 설정 */
}

/* 제목 스타일 설정 */
h1, .h1 {
    color: #343a40; /* 텍스트 색상 설정 */
}

/* 리스트 아이템 스타일 설정 */
.list-group-item {
    background: #fff; /* 배경색 설정 */
    margin-bottom: 10px; /* 아래쪽 여백 설정 */
    border: 1px solid #ddd; /* 테두리 설정 */
    border-radius: 4px; /* 모서리 둥글게 설정 */
}

/* 링크 스타일 설정 */
.btn-link {
    color: #007bff; /* 링크 색상 설정 */
    text-decoration: none; /* 밑줄 제거 */
}

.btn-link:hover {
    color: #0056b3; /* 호버 시 링크 색상 설정 */
    text-decoration: underline; /* 호버 시 밑줄 설정 */
}

/* 커스터마이즈된 버튼 색상 설정 */
.btn-primary {
    background-color: #A8DADC; /* 파스텔 블루 */
    border-color: #A8DADC;
    color: #fff; /* 텍스트 색상 설정 */
}

.btn-primary:hover {
    background-color: #457B9D; /* 호버 시 파스텔 블루 */
    border-color: #457B9D;
}

.btn-secondary {
    background-color: #F4A261; /* 파스텔 오렌지 */
    border-color: #F4A261;
    color: #fff; /* 텍스트 색상 설정 */
}

.btn-secondary:hover {
    background-color: #E76F51; /* 호버 시 파스텔 오렌지 */
    border-color: #E76F51;
}

.btn-danger {
    background-color: #E63946; /* 파스텔 레드 */
    border-color: #E63946;
    color: #fff; /* 텍스트 색상 설정 */
}

.btn-danger:hover {
    background-color: #D62828; /* 호버 시 파스텔 레드 */
    border-color: #D62828;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Comments