Web

Python Web Development: Từ Lập Trình Cơ Bản Đến Web App

Hướng dẫng xây dựng ứng dụng web với Python - từ kiến thức lập trình lớp 12 đến web framework hiện đại

10 phút đọc
NhiTuyen Tech Blog Team
Python Web Development: Từ Lập Trình Cơ Bản Đến Web App

Python Web Development: Từ Lập Trình Cơ Bản Đến Web App

Python không chỉ là ngôn ngữ lập trình bạn học ở lớp 12, mà còn là công cụ mạnh mẽ để xây dựng website và ứng dụng web! Hãy cùng khám phá cách biến kiến thức Python cơ bản thành web developer.

Python Web Development

Python Cơ Bản - Ôn Tập Kiến Thức Lớp 12

Biến và Kiểu Dữ Liệu

Chú thích: Đây là kiến thức nền tảng từ sách giáo khoa Tin học 12!

# Kiến thức cơ bản từ lớp 12
# Khai báo biến
name = "Nguyễn Văn A"          # Chuỗi (string)
age = 18                        # Số nguyên (integer)
score = 9.5                     # Số thực (float)
is_student = True               # Boolean

# List - Mảng trong Python
students = ["An", "Bình", "Chi"]
scores = [8.5, 9.0, 7.5]

# Dictionary - Từ điển (giống struct)
student = {
    "name": "Nguyễn Văn A",
    "age": 18,
    "class": "12A1"
}

print(f"Học sinh: {student['name']}, {student['age']} tuổi")
# Output: Học sinh: Nguyễn Văn A, 18 tuổi

Hàm (Function)

# Hàm tính điểm trung bình - Bài tập quen thuộc lớp 12!
def tinh_diem_trung_binh(mon1, mon2, mon3):
    """
    Tính điểm trung bình 3 môn
    Input: điểm 3 môn (float)
    Output: điểm TB (float)
    """
    return (mon1 + mon2 + mon3) / 3

# Sử dụng hàm
dtb = tinh_diem_trung_binh(8.5, 9.0, 7.5)
print(f"Điểm TB: {dtb:.2f}")  # Output: Điểm TB: 8.33

Vòng Lặp và Điều Kiện

# Bài toán: Tìm số nguyên tố
def la_so_nguyen_to(n):
    """
    Kiểm tra số nguyên tố - Bài tập Tin học 12
    """
    if n < 2:
        return False
    
    for i in range(2, int(n ** 0.5) + 1):
        if n % i == 0:
            return False
    
    return True

# Test
for num in range(1, 20):
    if la_so_nguyen_to(num):
        print(num, end=" ")
# Output: 2 3 5 7 11 13 17 19

Python Basics

Từ Console Đến Web

Hello World - Console vs Web

# Console App - Quen thuộc từ lớp 12
print("Hello, World!")
name = input("Nhập tên: ")
print(f"Xin chào {name}!")

# Web App - Cùng logic nhưng trên web!
# Flask framework
from flask import Flask, request, render_template

app = Flask(__name__)

@app.route('/')
def home():
    return "<h1>Hello, World!</h1>"

@app.route('/greet', methods=['GET', 'POST'])
def greet():
    if request.method == 'POST':
        name = request.form['name']
        return f"<h1>Xin chào {name}!</h1>"
    
    return '''
        <form method="post">
            <input name="name" placeholder="Nhập tên">
            <button>Gửi</button>
        </form>
    '''

if __name__ == '__main__':
    app.run(debug=True)

# Chạy và mở http://localhost:5000 🌐

Flask - Web Framework Đơn Giản

Chú thích: Flask là framework nhẹ, dễ học, phù hợp cho người mới bắt đầu từ lập trình cơ bản.

Cài Đặt Flask

# Cài Flask
pip install flask

# Tạo file app.py
# Chạy app
python app.py

Ứng Dụng Tính Điểm Trung Bình

# app.py - Bài tập từ lớp 12 lên Web!
from flask import Flask, render_template, request

app = Flask(__name__)

@app.route('/')
def home():
    return render_template('index.html')

@app.route('/calculate', methods=['POST'])
def calculate():
    # Lấy điểm từ form
    toan = float(request.form['toan'])
    ly = float(request.form['ly'])
    hoa = float(request.form['hoa'])
    
    # Tính điểm TB (logic từ lớp 12)
    dtb = (toan + ly + hoa) / 3
    
    # Xếp loại
    if dtb >= 8.0:
        xep_loai = "Giỏi"
    elif dtb >= 6.5:
        xep_loai = "Khá"
    elif dtb >= 5.0:
        xep_loai = "Trung bình"
    else:
        xep_loai = "Yếu"
    
    return render_template('result.html', 
                          dtb=round(dtb, 2), 
                          xep_loai=xep_loai)

if __name__ == '__main__':
    app.run(debug=True)

HTML Template

<!-- templates/index.html -->
<!DOCTYPE html>
<html lang="vi">
<head>
    <meta charset="UTF-8">
    <title>Tính Điểm Trung Bình</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 500px;
            margin: 50px auto;
            padding: 20px;
        }
        input {
            width: 100%;
            padding: 10px;
            margin: 10px 0;
            border: 1px solid #ddd;
            border-radius: 4px;
        }
        button {
            width: 100%;
            padding: 10px;
            background: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <h1>📊 Tính Điểm Trung Bình</h1>
    <form action="/calculate" method="post">
        <label>Toán:</label>
        <input type="number" name="toan" step="0.1" min="0" max="10" required>
        
        <label>Lý:</label>
        <input type="number" name="ly" step="0.1" min="0" max="10" required>
        
        <label>Hóa:</label>
        <input type="number" name="hoa" step="0.1" min="0" max="10" required>
        
        <button type="submit">Tính Điểm</button>
    </form>
</body>
</html>
<!-- templates/result.html -->
<!DOCTYPE html>
<html lang="vi">
<head>
    <meta charset="UTF-8">
    <title>Kết Quả</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 500px;
            margin: 50px auto;
            padding: 20px;
            text-align: center;
        }
        .result {
            background: #f0f0f0;
            padding: 30px;
            border-radius: 8px;
            margin: 20px 0;
        }
        .dtb {
            font-size: 48px;
            font-weight: bold;
            color: #007bff;
        }
        .xep-loai {
            font-size: 24px;
            color: #28a745;
            margin-top: 10px;
        }
    </style>
</head>
<body>
    <h1>📈 Kết Quả</h1>
    <div class="result">
        <div class="dtb">{{ dtb }}</div>
        <div class="xep-loai">{{ xep_loai }}</div>
    </div>
    <a href="/">← Tính lại</a>
</body>
</html>

Flask App

Xử Lý Form và Dữ Liệu

Quản Lý Danh Sách Học Sinh

# app.py - CRUD operations (Create, Read, Update, Delete)
from flask import Flask, render_template, request, redirect, url_for

app = Flask(__name__)

# Danh sách học sinh (trong thực tế sẽ dùng database)
students = [
    {"id": 1, "name": "Nguyễn Văn A", "class": "12A1", "score": 8.5},
    {"id": 2, "name": "Trần Thị B", "class": "12A2", "score": 9.0},
]

@app.route('/')
def index():
    return render_template('students.html', students=students)

@app.route('/add', methods=['GET', 'POST'])
def add_student():
    if request.method == 'POST':
        new_student = {
            "id": len(students) + 1,
            "name": request.form['name'],
            "class": request.form['class'],
            "score": float(request.form['score'])
        }
        students.append(new_student)
        return redirect(url_for('index'))
    
    return render_template('add_student.html')

@app.route('/delete/<int:student_id>')
def delete_student(student_id):
    global students
    students = [s for s in students if s['id'] != student_id]
    return redirect(url_for('index'))

@app.route('/search', methods=['GET'])
def search():
    query = request.args.get('q', '')
    results = [s for s in students if query.lower() in s['name'].lower()]
    return render_template('students.html', students=results)

if __name__ == '__main__':
    app.run(debug=True)

Kết Nối Database

Chú thích: Kiến thức CSDL từ lớp 12 áp dụng thực tế với SQLite!

SQLite - Database Đơn Giản

# database.py
import sqlite3

def init_db():
    """Tạo bảng HOCSINH giống SGK Tin học 12"""
    conn = sqlite3.connect('school.db')
    cursor = conn.cursor()
    
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS HOCSINH (
            MaHS INTEGER PRIMARY KEY AUTOINCREMENT,
            HoTen TEXT NOT NULL,
            Lop TEXT NOT NULL,
            DiemTB REAL NOT NULL,
            XepLoai TEXT
        )
    ''')
    
    conn.commit()
    conn.close()

def them_hoc_sinh(ho_ten, lop, diem_tb):
    """Thêm học sinh vào CSDL"""
    # Xếp loại tự động
    if diem_tb >= 8.0:
        xep_loai = "Giỏi"
    elif diem_tb >= 6.5:
        xep_loai = "Khá"
    elif diem_tb >= 5.0:
        xep_loai = "Trung bình"
    else:
        xep_loai = "Yếu"
    
    conn = sqlite3.connect('school.db')
    cursor = conn.cursor()
    
    cursor.execute('''
        INSERT INTO HOCSINH (HoTen, Lop, DiemTB, XepLoai)
        VALUES (?, ?, ?, ?)
    ''', (ho_ten, lop, diem_tb, xep_loai))
    
    conn.commit()
    conn.close()

def lay_danh_sach_hoc_sinh():
    """Truy vấn SELECT - Kiến thức SQL lớp 12"""
    conn = sqlite3.connect('school.db')
    cursor = conn.cursor()
    
    cursor.execute('SELECT * FROM HOCSINH ORDER BY DiemTB DESC')
    students = cursor.fetchall()
    
    conn.close()
    return students

# Khởi tạo database
init_db()

Flask App với Database

# app_with_db.py
from flask import Flask, render_template, request, redirect
import sqlite3
from database import init_db, them_hoc_sinh, lay_danh_sach_hoc_sinh

app = Flask(__name__)
init_db()

@app.route('/')
def index():
    students = lay_danh_sach_hoc_sinh()
    return render_template('students_db.html', students=students)

@app.route('/add', methods=['GET', 'POST'])
def add():
    if request.method == 'POST':
        ho_ten = request.form['name']
        lop = request.form['class']
        diem_tb = float(request.form['score'])
        
        them_hoc_sinh(ho_ten, lop, diem_tb)
        return redirect('/')
    
    return render_template('add_student.html')

@app.route('/stats')
def statistics():
    """Thống kê - Bài tập thường gặp lớp 12"""
    conn = sqlite3.connect('school.db')
    cursor = conn.cursor()
    
    # Đếm số học sinh theo xếp loại
    cursor.execute('''
        SELECT XepLoai, COUNT(*) as SoLuong
        FROM HOCSINH
        GROUP BY XepLoai
    ''')
    stats = cursor.fetchall()
    
    # Điểm TB cao nhất, thấp nhất
    cursor.execute('SELECT MAX(DiemTB), MIN(DiemTB), AVG(DiemTB) FROM HOCSINH')
    max_score, min_score, avg_score = cursor.fetchone()
    
    conn.close()
    
    return render_template('stats.html', 
                          stats=stats,
                          max_score=max_score,
                          min_score=min_score,
                          avg_score=round(avg_score, 2))

if __name__ == '__main__':
    app.run(debug=True)

Database

RESTful API

Tạo API Đơn Giản

# api.py - API cho ứng dụng mobile/frontend
from flask import Flask, jsonify, request

app = Flask(__name__)

students = []

@app.route('/api/students', methods=['GET'])
def get_students():
    """Lấy danh sách học sinh - GET request"""
    return jsonify(students)

@app.route('/api/students/<int:student_id>', methods=['GET'])
def get_student(student_id):
    """Lấy 1 học sinh theo ID"""
    student = next((s for s in students if s['id'] == student_id), None)
    
    if student:
        return jsonify(student)
    else:
        return jsonify({"error": "Không tìm thấy học sinh"}), 404

@app.route('/api/students', methods=['POST'])
def create_student():
    """Thêm học sinh mới - POST request"""
    data = request.get_json()
    
    new_student = {
        "id": len(students) + 1,
        "name": data['name'],
        "class": data['class'],
        "score": data['score']
    }
    
    students.append(new_student)
    return jsonify(new_student), 201

@app.route('/api/students/<int:student_id>', methods=['PUT'])
def update_student(student_id):
    """Cập nhật học sinh - PUT request"""
    student = next((s for s in students if s['id'] == student_id), None)
    
    if not student:
        return jsonify({"error": "Không tìm thấy"}), 404
    
    data = request.get_json()
    student.update(data)
    
    return jsonify(student)

@app.route('/api/students/<int:student_id>', methods=['DELETE'])
def delete_student(student_id):
    """Xóa học sinh - DELETE request"""
    global students
    students = [s for s in students if s['id'] != student_id]
    
    return jsonify({"message": "Đã xóa"}), 200

if __name__ == '__main__':
    app.run(debug=True)

Test API với JavaScript

<!-- test_api.html -->
<!DOCTYPE html>
<html>
<head>
    <title>Test API</title>
</head>
<body>
    <h1>API Testing</h1>
    
    <button onclick="getStudents()">Lấy danh sách</button>
    <button onclick="addStudent()">Thêm học sinh</button>
    
    <div id="result"></div>
    
    <script>
        const API_URL = 'http://localhost:5000/api';
        
        // GET - Lấy danh sách
        async function getStudents() {
            const response = await fetch(`${API_URL}/students`);
            const data = await response.json();
            
            document.getElementById('result').innerHTML = 
                JSON.stringify(data, null, 2);
        }
        
        // POST - Thêm học sinh
        async function addStudent() {
            const response = await fetch(`${API_URL}/students`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    name: 'Nguyễn Văn C',
                    class: '12A3',
                    score: 8.5
                })
            });
            
            const data = await response.json();
            alert('Đã thêm: ' + data.name);
        }
    </script>
</body>
</html>

API Development

Django - Framework Mạnh Mẽ Hơn

Chú thích: Django là framework full-featured, phù hợp cho projects lớn hơn.

Setup Django Project

# Cài Django
pip install django

# Tạo project
django-admin startproject school_management

# Tạo app
cd school_management
python manage.py startapp students

# Chạy server
python manage.py runserver

Models - ORM

# students/models.py
from django.db import models

class Student(models.Model):
    """Model HOCSINH - ORM thay vì SQL thuần"""
    ho_ten = models.CharField(max_length=100)
    lop = models.CharField(max_length=10)
    diem_tb = models.FloatField()
    xep_loai = models.CharField(max_length=20, blank=True)
    
    def save(self, *args, **kwargs):
        # Tự động xếp loại khi lưu
        if self.diem_tb >= 8.0:
            self.xep_loai = "Giỏi"
        elif self.diem_tb >= 6.5:
            self.xep_loai = "Khá"
        elif self.diem_tb >= 5.0:
            self.xep_loai = "Trung bình"
        else:
            self.xep_loai = "Yếu"
        
        super().save(*args, **kwargs)
    
    def __str__(self):
        return f"{self.ho_ten} - {self.lop}"
    
    class Meta:
        db_table = 'HOCSINH'
        ordering = ['-diem_tb']

Views

# students/views.py
from django.shortcuts import render, redirect
from .models import Student

def student_list(request):
    """Danh sách học sinh"""
    students = Student.objects.all()
    return render(request, 'students/list.html', {'students': students})

def student_create(request):
    """Thêm học sinh"""
    if request.method == 'POST':
        Student.objects.create(
            ho_ten=request.POST['name'],
            lop=request.POST['class'],
            diem_tb=float(request.POST['score'])
        )
        return redirect('student_list')
    
    return render(request, 'students/create.html')

def statistics(request):
    """Thống kê"""
    from django.db.models import Count, Avg, Max, Min
    
    stats = Student.objects.values('xep_loai').annotate(
        count=Count('id')
    )
    
    scores = Student.objects.aggregate(
        max_score=Max('diem_tb'),
        min_score=Min('diem_tb'),
        avg_score=Avg('diem_tb')
    )
    
    return render(request, 'students/stats.html', {
        'stats': stats,
        'scores': scores
    })

Django Framework

Deployment - Đưa Web Lên Internet

Flask với Heroku (Free)

# Tạo requirements.txt
pip freeze > requirements.txt

# Tạo Procfile
echo "web: python app.py" > Procfile

# Deploy lên Heroku
heroku create my-school-app
git push heroku main

Flask với PythonAnywhere

# Upload code lên PythonAnywhere
# Cấu hình WSGI file
# Website live! 🌐

Bài Tập Thực Hành

Bài 1: Quản Lý Thư Viện

# Yêu cầu:
# - CSDL: SACH (MaSach, TenSach, TacGia, NamXB, SoLuong)
# - Chức năng: Thêm, xóa, sửa, tìm kiếm sách
# - Thống kê: Sách theo tác giả, năm XB
# - Giao diện web đẹp

# Gợi ý cấu trúc:
class Book(models.Model):
    ma_sach = models.AutoField(primary_key=True)
    ten_sach = models.CharField(max_length=200)
    tac_gia = models.CharField(max_length=100)
    nam_xb = models.IntegerField()
    so_luong = models.IntegerField(default=1)

Bài 2: Tra Cứu Điểm Thi

# Yêu cầu:
# - Nhập SBD, hiển thị điểm các môn
# - Tính tổng điểm, điểm chuẩn
# - Biểu đồ thống kê điểm
# - API cho mobile app

Bài 3: Blog Cá Nhân

# Yêu cầu:
# - Đăng bài viết (CRUD)
# - Categories, tags
# - Comment system
# - User authentication

Projects

Roadmap Học Python Web

# Lộ trình từ lớp 12 đến Web Developer
roadmap = {
    "Tháng 1-2": [
        "Ôn lại Python cơ bản",
        "Làm bài tập thuật toán",
        "Học HTML/CSS cơ bản"
    ],
    "Tháng 3-4": [
        "Flask cơ bản",
        "Database với SQLite",
        "Build 2-3 projects nhỏ"
    ],
    "Tháng 5-6": [
        "Django framework",
        "PostgreSQL",
        "Deploy lên Heroku"
    ],
    "Tháng 7+": [
        "REST API",
        "React/Vue frontend",
        "Full-stack developer! 🚀"
    ]
}

Kết Luận

Python Web Development giúp bạn:

  • ✅ Áp dụng kiến thức lập trình lớp 12 vào thực tế
  • ✅ Xây dựng ứng dụng web thực sự
  • ✅ Hiểu sâu về database và SQL
  • ✅ Tạo portfolio ấn tượng cho đại học/việc làm
  • ✅ Nền tảng cho career IT
# Bắt đầu hành trình của bạn!
def your_journey():
    skills = ["Python cơ bản"]  # Từ lớp 12
    
    skills.append("Flask")
    skills.append("Database")
    skills.append("Django")
    skills.append("Full-stack")
    
    return "Web Developer! 🎉"

print(your_journey())
# Output: Web Developer! 🎉

Success


Bạn đã thử build web app với Python chưa? Chia sẻ project của bạn! 💬

Tags

#Python #WebDevelopment #Flask #Django #Programming #TinHoc12 #Backend

Tags:

#Python #Web Development #Flask #Django #Backend #Programming

Chia sẻ bài viết:

Bài viết liên quan

Bài viết liên quan 1
Bài viết liên quan 2
Bài viết liên quan 3