Chào mừng các bạn đến với Rcom Dăm Yi blog - Kho tài liệu bổ ích!, Chúng tôi sẽ từng bước hoàn thiện để bạn đọc cảm thấy hài lòng, hữu ích!

Thứ Ba, 4 tháng 11, 2025

Bài 4: Flask + SQLite (CRUD hoàn chỉnh)

📘 BÀI 4: FLASK + SQLITE (CẬP NHẬT & XÓA DỮ LIỆU – CRUD HOÀN CHỈNH)


🎯 Mục tiêu bài học

  • Hiểu mô hình CRUD (Create – Read – Update – Delete).
  • Hoàn thiện ứng dụng Flask quản lý học sinh.
  • Tạo giao diện chỉnh sửa và xóa học sinh trực tiếp từ bảng dữ liệu.
CRUD Flask illustration

🧩 1. Cấu trúc thư mục dự án


flask_crud/
 ├─ app.py
 ├─ students.db
 └─ templates/
      ├─ index.html
      ├─ list.html
      └─ edit.html

⚙️ 2. File app.py


import sqlite3
from flask import Flask, render_template, request, redirect, url_for

app = Flask(__name__)

# --- Tạo database ---
def init_db():
    conn = sqlite3.connect('students.db')
    c = conn.cursor()
    c.execute('''CREATE TABLE IF NOT EXISTS students (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    hoten TEXT,
                    lop TEXT,
                    diem REAL
                )''')
    conn.commit()
    conn.close()

# --- Trang nhập học sinh ---
@app.route('/')
def index():
    return render_template('index.html')

# --- Lưu học sinh mới ---
@app.route('/add', methods=['POST'])
def add():
    hoten = request.form.get('hoten')
    lop = request.form.get('lop')
    diem = request.form.get('diem')
    conn = sqlite3.connect('students.db')
    c = conn.cursor()
    c.execute("INSERT INTO students (hoten, lop, diem) VALUES (?, ?, ?)",
              (hoten, lop, diem))
    conn.commit()
    conn.close()
    return redirect('/list')

# --- Xem danh sách ---
@app.route('/list')
def list_students():
    conn = sqlite3.connect('students.db')
    c = conn.cursor()
    c.execute("SELECT * FROM students")
    data = c.fetchall()
    conn.close()
    return render_template('list.html', students=data)

# --- Chỉnh sửa ---
@app.route('/edit/', methods=['GET', 'POST'])
def edit(id):
    conn = sqlite3.connect('students.db')
    c = conn.cursor()
    if request.method == 'POST':
        hoten = request.form.get('hoten')
        lop = request.form.get('lop')
        diem = request.form.get('diem')
        c.execute("UPDATE students SET hoten=?, lop=?, diem=? WHERE id=?",
                  (hoten, lop, diem, id))
        conn.commit()
        conn.close()
        return redirect(url_for('list_students'))
    else:
        c.execute("SELECT * FROM students WHERE id=?", (id,))
        data = c.fetchone()
        conn.close()
        return render_template('edit.html', hs=data)

# --- Xóa ---
@app.route('/delete/')
def delete(id):
    conn = sqlite3.connect('students.db')
    c = conn.cursor()
    c.execute("DELETE FROM students WHERE id=?", (id,))
    conn.commit()
    conn.close()
    return redirect('/list')

if __name__ == '__main__':
    init_db()
    app.run(debug=True)
💡 Giải thích:
- /edit/<id> hiển thị form chỉnh sửa học sinh theo mã.
- /delete/<id> xóa học sinh được chọn.
- url_for() giúp Flask điều hướng linh hoạt.

📋 3. File templates/index.html – Form thêm học sinh


<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<title>Thêm học sinh</title>
<style>
body { font-family: Arial; background: #e9f4ff; display: flex; justify-content: center; align-items: center; height: 100vh; }
.form-box { background: white; padding: 30px; border-radius: 8px; box-shadow: 0 0 10px rgba(0,0,0,0.2); width: 400px; }
input { width: 100%; padding: 8px; margin-top: 6px; border: 1px solid #ccc; border-radius: 5px; }
button { width: 100%; background: #2980b9; color: #fff; padding: 10px; border: none; border-radius: 5px; margin-top: 15px; }
a { display: block; text-align: center; margin-top: 10px; }
</style>
</head>
<body>
  <form class="form-box" action="/add" method="POST">
    <h2>➕ Thêm học sinh</h2>
    <label>Họ và tên:</label>
    <input type="text" name="hoten" required>
    <label>Lớp:</label>
    <input type="text" name="lop" required>
    <label>Điểm trung bình:</label>
    <input type="number" name="diem" min="0" max="10" step="0.1" required>
    <button type="submit">Lưu học sinh</button>
    <a href="/list">📋 Xem danh sách</a>
  </form>
</body>
</html>

📄 4. File templates/list.html – Danh sách học sinh


<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<title>Danh sách học sinh</title>
<style>
body { font-family: Arial; background: #f0f4f8; padding: 30px; }
table { width: 100%; border-collapse: collapse; margin-top: 15px; }
th, td { border: 1px solid #ccc; padding: 10px; text-align: center; }
th { background: #e9f2ff; }
a.button { background: #2980b9; color: white; padding: 6px 12px; border-radius: 5px; text-decoration: none; }
a.del { background: #e74c3c; }
</style>
</head>
<body>
  <h2>📚 Danh sách học sinh</h2>
  <table>
    <tr>
      <th>Mã</th><th>Họ tên</th><th>Lớp</th><th>Điểm TB</th><th>Hành động</th>
    </tr>
    {% for hs in students %}
    <tr>
      <td>{{ hs[0] }}</td><td>{{ hs[1] }}</td><td>{{ hs[2] }}</td><td>{{ hs[3] }}</td>
      <td>
        <a class="button" href="/edit/{{ hs[0] }}">✏️ Sửa</a>
        <a class="button del" href="/delete/{{ hs[0] }}" onclick="return confirm('Bạn có chắc muốn xóa?')">🗑️ Xóa</a>
      </td>
    </tr>
    {% endfor %}
  </table>
  <a href="/" class="button">➕ Thêm học sinh mới</a>
</body>
</html>

🧾 5. File templates/edit.html – Chỉnh sửa học sinh


<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<title>Chỉnh sửa học sinh</title>
<style>
body { font-family: Arial; background: #f0f4f8; display: flex; justify-content: center; align-items: center; height: 100vh; }
.form-box { background: white; padding: 30px; border-radius: 8px; box-shadow: 0 0 10px rgba(0,0,0,0.2); width: 400px; }
input { width: 100%; padding: 8px; margin-top: 6px; border: 1px solid #ccc; border-radius: 5px; }
button { width: 100%; background: #2980b9; color: #fff; padding: 10px; border: none; border-radius: 5px; margin-top: 15px; }
</style>
</head>
<body>
  <form class="form-box" method="POST">
    <h2>✏️ Cập nhật học sinh</h2>
    <label>Họ và tên:</label>
    <input type="text" name="hoten" value="{{ hs[1] }}" required>
    <label>Lớp:</label>
    <input type="text" name="lop" value="{{ hs[2] }}" required>
    <label>Điểm trung bình:</label>
    <input type="number" name="diem" value="{{ hs[3] }}" min="0" max="10" step="0.1" required>
    <button type="submit">Cập nhật</button>
    <a href="/list">⬅️ Quay lại</a>
  </form>
</body>
</html>

🏁 6. Kết quả khi chạy

Khi truy cập http://127.0.0.1:5000, bạn có thể:

  • ➕ Thêm học sinh
  • 📋 Xem danh sách
  • ✏️ Sửa học sinh
  • 🗑️ Xóa học sinh
Flask CRUD demo

🚀 7. Thử thách mở rộng cho học sinh

  • Thêm ô tìm kiếm theo tên hoặc lớp.
  • Thêm phân loại học lực (Giỏi – Khá – Trung bình).
  • Làm trang thống kê tổng số học sinh và điểm TB cao nhất.

📚 Kết luận

  • Bạn đã xây dựng được ứng dụng Flask hoàn chỉnh có cơ sở dữ liệu thực.
  • Đây là mô hình chuẩn CRUD trong lập trình web.
  • Có thể dùng kiến thức này để tạo ứng dụng quản lý học sinh, thư viện, hoặc câu lạc bộ trong trường.

© 2025 Trường THPT Phan Chu Trinh – Gia Lai | Bài giảng Flask – Phần 4: CRUD hoàn chỉnh

Không có nhận xét nào:

Đăng nhận xét

Bài đăng phổ biến

💬 Bình luận

💬 Bình luận

📌 Danh sách bình luận