Thứ Ba, 4 tháng 11, 2025

Bài 7: Flask + Upload hình ảnh học sinh + Thống kê nâng cao

🖼️ BÀI 7: UPLOAD ẢNH HỌC SINH + THỐNG KÊ NÂNG CAO

Thực hành Flask – Lưu hình ảnh và hiển thị thống kê nâng cao


🎯 Mục tiêu

  • Biết cách upload file ảnh trong Flask.
  • Lưu đường dẫn ảnh vào cơ sở dữ liệu.
  • Hiển thị hình ảnh học sinh và điểm số trên trang thống kê.
Flask upload demo

⚙️ 1. Cấu trúc dự án


flask_upload/
 ├─ app.py
 ├─ static/uploads/
 ├─ students.db
 └─ templates/
      ├─ upload.html
      ├─ gallery.html

💻 2. File app.py


from flask import Flask, render_template, request, redirect, url_for
import sqlite3, os
from werkzeug.utils import secure_filename

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'static/uploads'
app.secret_key = 'uploadkey'

# Tạo bảng
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,
                    diem REAL,
                    image TEXT
                )''')
    conn.commit()
    conn.close()

@app.route('/')
def upload_form():
    return render_template('upload.html')

@app.route('/upload', methods=['POST'])
def upload_file():
    hoten = request.form['hoten']
    diem = request.form['diem']
    file = request.files['image']
    if file:
        filename = secure_filename(file.filename)
        path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
        file.save(path)
        conn = sqlite3.connect('students.db')
        c = conn.cursor()
        c.execute("INSERT INTO students (hoten, diem, image) VALUES (?, ?, ?)", (hoten, diem, filename))
        conn.commit()
        conn.close()
    return redirect('/gallery')

@app.route('/gallery')
def gallery():
    conn = sqlite3.connect('students.db')
    c = conn.cursor()
    c.execute("SELECT hoten, diem, image FROM students")
    data = c.fetchall()
    conn.close()
    return render_template('gallery.html', students=data)

if __name__ == '__main__':
    os.makedirs('static/uploads', exist_ok=True)
    init_db()
    app.run(debug=True)

📋 3. File templates/upload.html


<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<title>Upload ảnh học sinh</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="bg-light d-flex justify-content-center align-items-center vh-100">
<form action="/upload" method="POST" enctype="multipart/form-data" class="p-4 bg-white shadow rounded" style="width:350px;">
  <h3 class="text-primary text-center mb-3">🖼️ Upload ảnh học sinh</h3>
  <input class="form-control mb-2" type="text" name="hoten" placeholder="Họ và tên" required>
  <input class="form-control mb-2" type="number" step="0.1" name="diem" placeholder="Điểm TB" required>
  <input class="form-control mb-3" type="file" name="image" accept="image/*" required>
  <button class="btn btn-success w-100">Tải lên</button>
  <a href="/gallery" class="d-block text-center mt-2">📸 Xem thư viện</a>
</form>
</body>
</html>

📷 4. File templates/gallery.html


<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<title>Thư viện học sinh</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="bg-light">
<div class="container mt-5">
  <h2 class="text-primary text-center mb-4">📸 Thư viện học sinh</h2>
  <div class="row">
    {% for hs in students %}
      <div class="col-md-3 mb-4">
        <div class="card shadow">
          <img src="{{ url_for('static', filename='uploads/' + hs[2]) }}" class="card-img-top" alt="{{ hs[0] }}">
          <div class="card-body text-center">
            <h5>{{ hs[0] }}</h5>
            <p>Điểm: {{ hs[1] }}</p>
          </div>
        </div>
      </div>
    {% endfor %}
  </div>
</div>
</body>
</html>

📈 5. Mở rộng nâng cao

  • Tính điểm TB toàn trường, hiển thị biểu đồ (Chart.js).
  • Tô màu khác nhau cho học sinh Giỏi / Khá / TB.
  • Cho phép upload nhiều ảnh cùng lúc.

© 2025 Trường THPT Phan Chu Trinh – Bài 7: Flask Upload + Thống kê nâng cao

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