🚀 หลักสูตร: การพัฒนาเว็บแอปพลิเคชันด้วย Python + Django

หลักสูตรสถาบันพัฒนาฝีมือแรงงาน 3 ชลบุรี (DSD)

📅 วันที่ 6, 7, 13, 14 ธันวาคม 2568

⏰ เวลา 08:30 - 17:00 น.

🎯 เป้าหมายหลักสูตร

ผู้เข้าอบรมจะได้เรียนรู้:

  • การเขียนโปรแกรม Python ตั้งแต่พื้นฐานจนถึง OOP
  • การพัฒนาเว็บด้วย HTML, CSS และการออกแบบที่ตอบสนอง (Responsive)
  • Django Framework สำหรับสร้างเว็บแอปพลิเคชันระดับมืออาชีพ
  • การทำงานกับฐานข้อมูลผ่าน Django ORM
  • การสร้างระบบ Authentication และ Authorization
  • การ Deploy เว็บแอปพลิเคชันจริง

💼 หลักสูตรนี้เหมาะสำหรับ:

  • ผู้ที่ต้องการเข้าสู่วงการ Web Development
  • นักพัฒนาที่ต้องการเรียนรู้ Python และ Django
  • ผู้ที่ต้องการสร้างเว็บแอปพลิเคชันของตัวเอง
  • ผู้ที่มีพื้นฐานการเขียนโปรแกรมเล็กน้อย (ไม่บังคับ)

📅 วันที่ 1: Python Foundation & OOP (6 ธ.ค. - ONSITE)

🌅 ช่วงเช้า (08:30-12:00)

1.1 ทำความรู้จักกับ Python และการติดตั้ง

1 ชั่วโมง Python Basics

📌 ทำไมต้อง Python?

  • ง่ายต่อการเรียนรู้: Syntax ที่อ่านง่ายคล้ายภาษาอังกฤษ
  • ใช้งานได้หลากหลาย: Web, Data Science, AI, Automation
  • Community ใหญ่: Library เยอะ ช่วยแก้ปัญหาง่าย
  • ตลาดต้องการสูง: งาน Python Developer เยอะมาก

📥 การติดตั้ง Python

  1. Download Python: python.org → Download Python 3.12+
  2. ติดตั้ง VS Code: code.visualstudio.com
  3. ติดตั้ง Extension: Python, Pylance
  4. ตรวจสอบการติดตั้ง:
# เปิด Terminal/Command Prompt python --version # ผลลัพธ์: Python 3.12.x # หรือ python3 --version

🔧 Virtual Environment

Virtual Environment คือ "กล่องแยก" สำหรับแต่ละโปรเจค เพื่อไม่ให้ Library ปะปนกัน

# สร้าง Virtual Environment python -m venv myenv # เปิดใช้งาน (Windows) myenv\Scripts\activate # เปิดใช้งาน (Mac/Linux) source myenv/bin/activate # เมื่อเปิดแล้วจะเห็น (myenv) หน้า command line
ตัวอย่าง

💡 โปรแกรมแรก: คำนวณค่า BMI

# โปรแกรมคำนวณค่า BMI (Body Mass Index) print("=== คำนวณค่า BMI ===") # รับข้อมูลจากผู้ใช้ weight = float(input("น้ำหนัก (kg): ")) height = float(input("ส่วนสูง (m): ")) # คำนวณ BMI bmi = weight / (height ** 2) # แสดงผล print(f"ค่า BMI ของคุณ: {bmi:.2f}") # ประเมินผล if bmi < 18.5: print("ผอมเกินไป") elif bmi < 25: print("น้ำหนักปกติ") elif bmi < 30: print("น้ำหนักเกิน") else: print("อ้วน")

ทดลองรัน: น้ำหนัก 70 kg, ส่วนสูง 1.75 m → BMI = 22.86 (น้ำหนักปกติ)

1.2 Python Basics

2 ชั่วโมง Core Concepts

📦 ตัวแปรและชนิดข้อมูล (Variables & Data Types)

1. String (ข้อความ)

# สร้างตัวแปร String name = "สมชาย" company = 'บริษัท ABC จำกัด' address = """123 ถนนสุขุมวิท กรุงเทพมหานคร 10110""" # การต่อ String fullname = "คุณ" + name # "คุณสมชาย" # f-string (แนะนำ) message = f"สวัสดีครับ {name} จาก {company}" # Methods ที่ใช้บ่อย print(name.upper()) # "สมชาย" print(name.lower()) # "สมชาย" print(len(name)) # 5 (จำนวนตัวอักษร)

2. Numbers (ตัวเลข)

# Integer (จำนวนเต็ม) age = 25 salary = 50000 # Float (ทศนิยม) height = 1.75 price = 99.99 # การคำนวณ total = salary * 12 # 600000 bonus = salary * 0.1 # 5000.0 tax = (salary - 60000) * 0.05 # ภาษี # ฟังก์ชันทางคณิตศาสตร์ import math print(math.sqrt(16)) # 4.0 print(math.ceil(4.2)) # 5 print(math.floor(4.8)) # 4

3. List (รายการ)

# สร้าง List fruits = ["แอปเปิล", "กล้วย", "ส้ม"] numbers = [1, 2, 3, 4, 5] mixed = ["ข้อความ", 100, 3.14, True] # เข้าถึงข้อมูล (Index เริ่มที่ 0) print(fruits[0]) # "แอปเปิล" print(fruits[-1]) # "ส้ม" (นับจากท้าย) # เพิ่มข้อมูล fruits.append("องุ่น") # เพิ่มท้าย fruits.insert(0, "มะม่วง") # เพิ่มตำแหน่งที่ 0 # ลบข้อมูล fruits.remove("กล้วย") # ลบตามค่า fruits.pop() # ลบตัวสุดท้าย # Loop ผ่าน List for fruit in fruits: print(f"ผลไม้: {fruit}") # List Comprehension (เทคนิคขั้นสูง) squares = [x**2 for x in range(1, 6)] # [1, 4, 9, 16, 25]

4. Dictionary (พจนานุกรม)

# สร้าง Dictionary (คีย์-ค่า) person = { "name": "สมชาย", "age": 25, "city": "กรุงเทพ", "salary": 50000 } # เข้าถึงข้อมูล print(person["name"]) # "สมชาย" print(person.get("age")) # 25 # เพิ่ม/แก้ไขข้อมูล person["email"] = "somchai@email.com" person["age"] = 26 # ลบข้อมูล del person["city"] # Loop ผ่าน Dictionary for key, value in person.items(): print(f"{key}: {value}") # ตัวอย่างการใช้งานจริง: สินค้า product = { "id": "P001", "name": "โน้ตบุ๊ค", "price": 25000, "stock": 10 }

🔄 Control Flow (การควบคุมโปรแกรม)

1. If-Elif-Else

# ตัวอย่าง: เกรด score = 85 if score >= 80: grade = "A" elif score >= 70: grade = "B" elif score >= 60: grade = "C" elif score >= 50: grade = "D" else: grade = "F" print(f"คะแนน {score} ได้เกรด {grade}") # Multiple Conditions age = 25 has_license = True if age >= 18 and has_license: print("สามารถขับรถได้") elif age >= 18 and not has_license: print("ต้องมีใบขับขี่ก่อน") else: print("ยังเด็กเกินไป")

2. Loops (การวนซ้ำ)

# For Loop - วนตามจำนวนที่กำหนด for i in range(5): print(f"รอบที่ {i+1}") # For Loop - วนผ่าน List employees = ["สมชาย", "สมหญิง", "สมศรี"] for emp in employees: print(f"พนักงาน: {emp}") # While Loop - วนจนกว่าเงื่อนไขจะเป็นเท็จ count = 0 while count < 5: print(f"Count: {count}") count += 1 # Break & Continue for i in range(10): if i == 3: continue # ข้ามรอบนี้ if i == 7: break # หยุด loop print(i)
Workshop

🔨 Workshop: ระบบคำนวณเงินเดือนพนักงาน

โจทย์: สร้างโปรแกรมคำนวณเงินเดือนพนักงานที่มี:

  • เงินเดือนพื้นฐาน
  • โบนัส 10% (ถ้าทำงานครบ 1 ปี)
  • ค่า OT 150 บาท/ชั่วโมง
  • หัก ประกันสังคม 5%
# ระบบคำนวณเงินเดือน print("=== ระบบคำนวณเงินเดือนพนักงาน ===\n") # รับข้อมูล name = input("ชื่อพนักงาน: ") basic_salary = float(input("เงินเดือนพื้นฐาน: ")) years = int(input("อายุงาน (ปี): ")) ot_hours = float(input("ชั่วโมง OT: ")) # คำนวณ bonus = 0 if years >= 1: bonus = basic_salary * 0.10 ot_pay = ot_hours * 150 gross_salary = basic_salary + bonus + ot_pay social_security = gross_salary * 0.05 net_salary = gross_salary - social_security # แสดงผล print(f"\n{'='*40}") print(f"สรุปเงินเดือนของ {name}") print(f"{'='*40}") print(f"เงินเดือนพื้นฐาน: {basic_salary:>10,.2f} บาท") print(f"โบนัส: {bonus:>10,.2f} บาท") print(f"ค่า OT: {ot_pay:>10,.2f} บาท") print(f"{'='*40}") print(f"รวมรายได้: {gross_salary:>10,.2f} บาท") print(f"หัก ประกันสังคม: {social_security:>10,.2f} บาท") print(f"{'='*40}") print(f"เงินสุทธิ: {net_salary:>10,.2f} บาท")

ผลลัพธ์ตัวอย่าง:

ชื่อพนักงาน: สมชาย เงินเดือนพื้นฐาน: 30000 อายุงาน (ปี): 2 ชั่วโมง OT: 10 ======================================== สรุปเงินเดือนของ สมชาย ======================================== เงินเดือนพื้นฐาน: 30,000.00 บาท โบนัส: 3,000.00 บาท ค่า OT: 1,500.00 บาท ======================================== รวมรายได้: 34,500.00 บาท หัก ประกันสังคม: 1,725.00 บาท ======================================== เงินสุทธิ: 32,775.00 บาท

1.3 Functions & Modules

30 นาที Code Organization

📝 Functions (ฟังก์ชัน)

ฟังก์ชันคือ "กล่องโค้ด" ที่ทำงานเฉพาะอย่าง สามารถเรียกใช้ซ้ำได้

การสร้างและใช้งาน Function

# Function พื้นฐาน def greet(name): """ฟังก์ชันทักทาย""" return f"สวัสดี {name}" # เรียกใช้ message = greet("สมชาย") print(message) # "สวัสดี สมชาย" # Function หลายพารามิเตอร์ def calculate_salary(basic, bonus_rate, ot_hours): """คำนวณเงินเดือน""" bonus = basic * bonus_rate ot_pay = ot_hours * 150 return basic + bonus + ot_pay # เรียกใช้ total = calculate_salary(30000, 0.1, 10) print(f"เงินเดือนรวม: {total:,.2f} บาท") # Function ที่มีค่าเริ่มต้น def create_employee(name, department="ฝ่ายขาย", salary=25000): return { "name": name, "department": department, "salary": salary } emp1 = create_employee("สมชาย") emp2 = create_employee("สมหญิง", "ฝ่ายบัญชี", 30000) # Function Return หลายค่า def calculate_stats(numbers): """คำนวณสถิติพื้นฐาน""" total = sum(numbers) avg = total / len(numbers) maximum = max(numbers) minimum = min(numbers) return total, avg, maximum, minimum # เรียกใช้ data = [10, 20, 30, 40, 50] sum_val, avg_val, max_val, min_val = calculate_stats(data)

📦 Modules (โมดูล)

Module คือไฟล์ Python ที่เก็บ Functions ไว้ใช้งานร่วมกัน

การสร้างและใช้งาน Module

1. สร้างไฟล์ tax_calculator.py

# tax_calculator.py """โมดูลคำนวณภาษี""" def calculate_vat(amount, rate=0.07): """คำนวณภาษีมูลค่าเพิ่ม (VAT)""" return amount * rate def calculate_income_tax(income): """คำนวณภาษีเงินได้""" if income <= 150000: return 0 elif income <= 300000: return (income - 150000) * 0.05 elif income <= 500000: return 7500 + (income - 300000) * 0.10 elif income <= 750000: return 27500 + (income - 500000) * 0.15 else: return 65000 + (income - 750000) * 0.20 def calculate_social_security(salary): """คำนวณประกันสังคม""" max_salary = 15000 rate = 0.05 base = min(salary, max_salary) return base * rate

2. ใช้งาน Module ในไฟล์อื่น

# main.py import tax_calculator # หรือ from tax_calculator import calculate_vat, calculate_income_tax # ใช้งาน price = 10000 vat = calculate_vat(price) print(f"ราคา: {price:,.2f} บาท") print(f"VAT 7%: {vat:,.2f} บาท") print(f"รวม: {price + vat:,.2f} บาท") # คำนวณภาษีเงินได้ annual_income = 600000 tax = calculate_income_tax(annual_income) print(f"\nรายได้ต่อปี: {annual_income:,.2f} บาท") print(f"ภาษีที่ต้องจ่าย: {tax:,.2f} บาท")
ตัวอย่าง

💡 สร้าง Utility Functions สำหรับคำนวณภาษี

# utils.py - ไฟล์เก็บ Utility Functions def format_currency(amount): """แปลงตัวเลขเป็นรูปแบบเงิน""" return f"{amount:,.2f} บาท" def calculate_net_salary(gross_salary, tax_rate=0.05): """คำนวณเงินเดือนสุทธิ""" tax = gross_salary * tax_rate net = gross_salary - tax return { "gross": gross_salary, "tax": tax, "net": net } def validate_salary(salary): """ตรวจสอบความถูกต้องของเงินเดือน""" if salary < 0: return False, "เงินเดือนต้องมากกว่า 0" if salary < 10000: return False, "เงินเดือนต่ำกว่าขั้นต่ำ" return True, "OK" # การใช้งาน if __name__ == "__main__": salary = 50000 result = calculate_net_salary(salary) print(f"เงินเดือนรวม: {format_currency(result['gross'])}") print(f"หักภาษี: {format_currency(result['tax'])}") print(f"เงินสุทธิ: {format_currency(result['net'])}")

🌆 ช่วงบ่าย (13:00-17:00)

1.4 Object-Oriented Programming (OOP)

2.5 ชั่วโมง Advanced

🎯 เป้าหมาย

เข้าใจแนวคิด OOP และสามารถสร้าง Class สำหรับจัดการข้อมูลได้

🏗️ แนวคิด OOP

OOP คือการเขียนโปรแกรมโดยมอง "สิ่งของ" เป็น Object ที่มี:

  • Attributes: คุณลักษณะ (เช่น รถมี สี, ยี่ห้อ, ราคา)
  • Methods: พฤติกรรม (เช่น รถสามารถ ขับ, เบรก, เติมน้ำมัน)

1. Class และ Object

# Class = แม่พิมพ์ (Blueprint) class Car: """คลาสรถยนต์""" def __init__(self, brand, color, price): """Constructor - กำหนดค่าเริ่มต้น""" self.brand = brand self.color = color self.price = price self.fuel = 100 # ค่าเริ่มต้น def drive(self, distance): """ขับรถ""" fuel_needed = distance * 0.1 if self.fuel >= fuel_needed: self.fuel -= fuel_needed return f"ขับไป {distance} km เหลือน้ำมัน {self.fuel:.1f}%" else: return "น้ำมันไม่พอ!" def refuel(self): """เติมน้ำมัน""" self.fuel = 100 return "เติมน้ำมันเต็มแล้ว" def get_info(self): """แสดงข้อมูลรถ""" return f"{self.color} {self.brand} ราคา {self.price:,.0f} บาท" # Object = สิ่งที่สร้างจาก Class car1 = Car("Toyota", "แดง", 500000) car2 = Car("Honda", "ขาว", 600000) # เรียกใช้ Method print(car1.get_info()) print(car1.drive(50)) print(car1.refuel())

2. Inheritance (การสืบทอด)

Class ลูกสามารถรับคุณสมบัติจาก Class แม่

# Class แม่ class BankAccount: """บัญชีธนาคารทั่วไป""" def __init__(self, account_no, owner, balance=0): self.account_no = account_no self.owner = owner self.balance = balance def deposit(self, amount): """ฝากเงิน""" self.balance += amount return f"ฝาก {amount:,.0f} บาท คงเหลือ {self.balance:,.0f} บาท" def withdraw(self, amount): """ถอนเงิน""" if amount <= self.balance: self.balance -= amount return f"ถอน {amount:,.0f} บาท คงเหลือ {self.balance:,.0f} บาท" return "เงินไม่พอ!" def get_balance(self): """เช็คยอด""" return f"ยอดเงินคงเหลือ: {self.balance:,.0f} บาท" # Class ลูก 1: บัญชีออมทรัพย์ class SavingAccount(BankAccount): """บัญชีออมทรัพย์ (มีดอกเบี้ย)""" def __init__(self, account_no, owner, balance=0, interest_rate=0.015): super().__init__(account_no, owner, balance) self.interest_rate = interest_rate def add_interest(self): """เพิ่มดอกเบี้ย""" interest = self.balance * self.interest_rate self.balance += interest return f"ได้ดอกเบี้ย {interest:,.2f} บาท" # Class ลูก 2: บัญชีกระแสรายวัน class CurrentAccount(BankAccount): """บัญชีกระแสรายวัน (ถอนเกินได้)""" def __init__(self, account_no, owner, balance=0, overdraft_limit=5000): super().__init__(account_no, owner, balance) self.overdraft_limit = overdraft_limit def withdraw(self, amount): """ถอนเงิน (ถอนเกินได้)""" if amount <= self.balance + self.overdraft_limit: self.balance -= amount return f"ถอน {amount:,.0f} บาท คงเหลือ {self.balance:,.0f} บาท" return f"ไม่สามารถถอนได้ (วงเงิน overdraft: {self.overdraft_limit:,.0f})" # การใช้งาน saving = SavingAccount("001", "สมชาย", 10000) print(saving.deposit(5000)) print(saving.add_interest()) print(saving.get_balance()) current = CurrentAccount("002", "สมหญิง", 1000, overdraft_limit=3000) print(current.withdraw(3500)) # ถอนเกินได้ print(current.get_balance())

3. Encapsulation (การห่อหุ้ม)

ซ่อนข้อมูลสำคัญ ป้องกันการเข้าถึงโดยตรง

class SecureBankAccount: """บัญชีที่มีความปลอดภัย""" def __init__(self, account_no, owner, pin): self.account_no = account_no self.owner = owner self.__balance = 0 # Private attribute self.__pin = pin # Private attribute self.__locked = False # Private attribute def verify_pin(self, pin): """ตรวจสอบ PIN""" return pin == self.__pin def deposit(self, amount, pin): """ฝากเงิน (ต้องใช้ PIN)""" if not self.verify_pin(pin): return "PIN ไม่ถูกต้อง!" self.__balance += amount return f"ฝาก {amount:,.0f} บาท สำเร็จ" def withdraw(self, amount, pin): """ถอนเงิน (ต้องใช้ PIN)""" if self.__locked: return "บัญชีถูกล็อค! กรุณาติดต่อธนาคาร" if not self.verify_pin(pin): return "PIN ไม่ถูกต้อง!" if amount <= self.__balance: self.__balance -= amount return f"ถอน {amount:,.0f} บาท สำเร็จ" return "เงินไม่พอ!" def get_balance(self, pin): """เช็คยอด (ต้องใช้ PIN)""" if not self.verify_pin(pin): return "PIN ไม่ถูกต้อง!" return f"ยอดเงิน: {self.__balance:,.0f} บาท" def change_pin(self, old_pin, new_pin): """เปลี่ยน PIN""" if not self.verify_pin(old_pin): return "PIN เดิมไม่ถูกต้อง!" self.__pin = new_pin return "เปลี่ยน PIN สำเร็จ" # การใช้งาน account = SecureBankAccount("123", "สมชาย", "1234") print(account.deposit(10000, "1234")) print(account.withdraw(3000, "1234")) print(account.get_balance("1234")) print(account.withdraw(3000, "9999")) # PIN ผิด

4. Polymorphism (พหุสัณฐาน)

Class ต่างกันสามารถมี Method ชื่อเดียวกันได้ แต่ทำงานต่างกัน

class Dog: def speak(self): return "โฮ่ง โฮ่ง!" class Cat: def speak(self): return "เหมียว!" class Cow: def speak(self): return "มอ~" # Polymorphism ในการใช้งาน animals = [Dog(), Cat(), Cow()] for animal in animals: print(f"{animal.__class__.__name__}: {animal.speak()}") # ผลลัพธ์: # Dog: โฮ่ง โฮ่ง! # Cat: เหมียว! # Cow: มอ~
Workshop

🔨 Workshop: ระบบจัดการบัญชีธนาคาร

โจทย์: สร้างระบบบัญชีธนาคารที่มี 3 ประเภท

# bank_system.py from datetime import datetime class BankAccount: """บัญชีธนาคารพื้นฐาน""" account_count = 0 # Class variable def __init__(self, owner, initial_balance=0): BankAccount.account_count += 1 self.account_no = f"ACC{BankAccount.account_count:04d}" self.owner = owner self.balance = initial_balance self.transactions = [] self._add_transaction("เปิดบัญชี", initial_balance) def _add_transaction(self, type, amount): """บันทึกรายการ (Private method)""" self.transactions.append({ "datetime": datetime.now(), "type": type, "amount": amount, "balance": self.balance }) def deposit(self, amount): """ฝากเงิน""" if amount <= 0: return "จำนวนเงินต้องมากกว่า 0" self.balance += amount self._add_transaction("ฝาก", amount) return f"ฝาก {amount:,.0f} บาท สำเร็จ" def withdraw(self, amount): """ถอนเงิน""" if amount <= 0: return "จำนวนเงินต้องมากกว่า 0" if amount > self.balance: return "เงินในบัญชีไม่พอ" self.balance -= amount self._add_transaction("ถอน", amount) return f"ถอน {amount:,.0f} บาท สำเร็จ" def get_balance(self): """เช็คยอด""" return f"บัญชี {self.account_no} ({self.owner}): {self.balance:,.0f} บาท" def print_statement(self): """พิมพ์สเตทเม้นท์""" print(f"\n{'='*60}") print(f"สเตทเม้นท์บัญชี: {self.account_no}") print(f"ชื่อบัญชี: {self.owner}") print(f"{'='*60}") print(f"{'วันที่/เวลา':<20} {'รายการ':<15} {'จำนวน':>12} {'คงเหลือ':>12}") print(f"{'-'*60}") for trans in self.transactions: dt = trans['datetime'].strftime('%Y-%m-%d %H:%M:%S') print(f"{dt:<20} {trans['type']:<15} {trans['amount']:>12,.0f} {trans['balance']:>12,.0f}") print(f"{'='*60}") print(f"ยอดเงินคงเหลือ: {self.balance:>34,.0f} บาท") print(f"{'='*60}\n") class SavingAccount(BankAccount): """บัญชีออมทรัพย์""" def __init__(self, owner, initial_balance=0, interest_rate=1.5): super().__init__(owner, initial_balance) self.interest_rate = interest_rate / 100 # แปลงเป็นทศนิยม def add_interest(self): """เพิ่มดอกเบี้ยรายปี""" interest = self.balance * self.interest_rate self.balance += interest self._add_transaction("ดอกเบี้ย", interest) return f"ได้รับดอกเบี้ย {interest:,.2f} บาท ({self.interest_rate*100}%)" class CurrentAccount(BankAccount): """บัญชีกระแสรายวัน""" def __init__(self, owner, initial_balance=0, overdraft_limit=5000): super().__init__(owner, initial_balance) self.overdraft_limit = overdraft_limit def withdraw(self, amount): """ถอนเงิน (ถอนเกินได้)""" if amount <= 0: return "จำนวนเงินต้องมากกว่า 0" if amount > self.balance + self.overdraft_limit: return f"ไม่สามารถถอนได้ (วงเงิน overdraft: {self.overdraft_limit:,.0f} บาท)" self.balance -= amount self._add_transaction("ถอน", amount) return f"ถอน {amount:,.0f} บาท สำเร็จ" def get_overdraft_status(self): """ตรวจสอบสถานะ overdraft""" if self.balance >= 0: return f"ยอดคงเหลือ: {self.balance:,.0f} บาท (ไม่ใช้ overdraft)" else: used = abs(self.balance) remaining = self.overdraft_limit - used return f"ใช้ overdraft: {used:,.0f} บาท (คงเหลือ: {remaining:,.0f} บาท)" class FixedDeposit(BankAccount): """บัญชีฝากประจำ""" def __init__(self, owner, amount, term_months, interest_rate=2.5): super().__init__(owner, amount) self.term_months = term_months self.interest_rate = interest_rate / 100 self.maturity_date = None self._locked = True def withdraw(self, amount): """ถอนก่อนกำหนด (มีค่าปรับ)""" if self._locked: penalty = amount * 0.02 # ปรับ 2% net_amount = amount - penalty self.balance -= amount self._add_transaction(f"ถอนก่อนกำหนด (ปรับ {penalty:,.2f})", amount) return f"ถอน {net_amount:,.2f} บาท (หักค่าปรับ {penalty:,.2f} บาท)" return super().withdraw(amount) def mature(self): """ครบกำหนด""" total_interest = self.balance * self.interest_rate * (self.term_months / 12) self.balance += total_interest self._locked = False self._add_transaction("ครบกำหนด", total_interest) return f"ครบกำหนด! ได้รับดอกเบี้ย {total_interest:,.2f} บาท" # ทดสอบระบบ if __name__ == "__main__": # สร้างบัญชีออมทรัพย์ saving = SavingAccount("สมชาย", 10000, interest_rate=1.5) print(saving.deposit(5000)) print(saving.withdraw(2000)) print(saving.add_interest()) saving.print_statement() # สร้างบัญชีกระแสรายวัน current = CurrentAccount("สมหญิง", 1000, overdraft_limit=5000) print(current.withdraw(3000)) # ถอนเกิน print(current.get_overdraft_status()) current.print_statement() # สร้างบัญชีฝากประจำ fixed = FixedDeposit("สมศรี", 50000, term_months=12, interest_rate=2.5) print(fixed.mature()) fixed.print_statement()

1.5 Exception Handling (การจัดการข้อผิดพลาด)

1 ชั่วโมง Error Management

🚨 ทำไมต้องจัดการ Error?

  • ป้องกันโปรแกรม Crash
  • แสดงข้อความที่เป็นมิตรกับผู้ใช้
  • Log ข้อผิดพลาดเพื่อ Debug
  • ทำให้โปรแกรมทำงานต่อได้แม้เจอปัญหา

1. Try-Except พื้นฐาน

# ตัวอย่างที่ผิดพลาด (ไม่มี Error Handling) number = int(input("กรอกตัวเลข: ")) # ถ้าใส่ตัวอักษร → Error! # แก้ไขด้วย Try-Except try: number = int(input("กรอกตัวเลข: ")) result = 100 / number print(f"ผลลัพธ์: {result}") except ValueError: print("❌ กรุณากรอกตัวเลขเท่านั้น!") except ZeroDivisionError: print("❌ ไม่สามารถหารด้วย 0 ได้!") except Exception as e: print(f"❌ เกิดข้อผิดพลาด: {e}")

2. Try-Except-Else-Finally

def read_file(filename): """อ่านไฟล์พร้อมจัดการ Error""" try: file = open(filename, 'r', encoding='utf-8') content = file.read() except FileNotFoundError: print(f"❌ ไม่พบไฟล์: {filename}") return None except PermissionError: print(f"❌ ไม่มีสิทธิ์เข้าถึงไฟล์: {filename}") return None else: # ทำงานถ้าไม่มี Error print(f"✅ อ่านไฟล์สำเร็จ") return content finally: # ทำงานเสมอ ไม่ว่าจะมี Error หรือไม่ try: file.close() print("ปิดไฟล์แล้ว") except: pass # การใช้งาน data = read_file("data.txt") if data: print(data)

3. Raise Exception (โยน Error เอง)

def withdraw(balance, amount): """ถอนเงิน""" if amount <= 0: raise ValueError("จำนวนเงินต้องมากกว่า 0") if amount > balance: raise ValueError(f"เงินไม่พอ! (มี {balance:,.0f} บาท)") return balance - amount # การใช้งาน try: new_balance = withdraw(1000, 1500) print(f"ถอนเงินสำเร็จ คงเหลือ {new_balance:,.0f} บาท") except ValueError as e: print(f"❌ {e}")

4. Custom Exception

# สร้าง Exception เอง class InsufficientFundsError(Exception): """Error เมื่อเงินไม่พอ""" pass class InvalidAmountError(Exception): """Error เมื่อจำนวนเงินไม่ถูกต้อง""" pass class BankAccount: def __init__(self, balance): self.balance = balance def withdraw(self, amount): """ถอนเงิน""" if amount <= 0: raise InvalidAmountError(f"จำนวนเงินไม่ถูกต้อง: {amount}") if amount > self.balance: raise InsufficientFundsError( f"เงินไม่พอ! ต้องการ {amount:,.0f} บาท " f"แต่มีเพียง {self.balance:,.0f} บาท" ) self.balance -= amount return self.balance # การใช้งาน account = BankAccount(5000) try: account.withdraw(-100) except InvalidAmountError as e: print(f"❌ {e}") try: account.withdraw(10000) except InsufficientFundsError as e: print(f"❌ {e}") try: new_balance = account.withdraw(3000) print(f"✅ ถอนสำเร็จ คงเหลือ {new_balance:,.0f} บาท") except (InvalidAmountError, InsufficientFundsError) as e: print(f"❌ {e}")
Workshop

🔨 Workshop: ปรับปรุงระบบธนาคารด้วย Error Handling

# bank_with_error_handling.py class InvalidAmountError(Exception): """จำนวนเงินไม่ถูกต้อง""" pass class InsufficientFundsError(Exception): """เงินไม่พอ""" pass class AccountLockedError(Exception): """บัญชีถูกล็อค""" pass class BankAccount: def __init__(self, account_no, owner, balance=0): self.account_no = account_no self.owner = owner self.balance = balance self.locked = False self.failed_attempts = 0 def deposit(self, amount): """ฝากเงิน""" try: if self.locked: raise AccountLockedError("บัญชีถูกล็อค กรุณาติดต่อธนาคาร") if amount <= 0: raise InvalidAmountError("จำนวนเงินต้องมากกว่า 0") self.balance += amount return f"✅ ฝาก {amount:,.0f} บาท สำเร็จ คงเหลือ {self.balance:,.0f} บาท" except (InvalidAmountError, AccountLockedError) as e: return f"❌ {e}" def withdraw(self, amount, pin): """ถอนเงิน""" try: if self.locked: raise AccountLockedError("บัญชีถูกล็อค กรุณาติดต่อธนาคาร") # ตรวจสอบ PIN if not self._verify_pin(pin): self.failed_attempts += 1 if self.failed_attempts >= 3: self.locked = True raise AccountLockedError("PIN ผิด 3 ครั้ง บัญชีถูกล็อคแล้ว!") raise ValueError(f"PIN ไม่ถูกต้อง! (เหลือ {3-self.failed_attempts} ครั้ง)") # Reset failed attempts self.failed_attempts = 0 if amount <= 0: raise InvalidAmountError("จำนวนเงินต้องมากกว่า 0") if amount > self.balance: raise InsufficientFundsError( f"เงินไม่พอ! ต้องการ {amount:,.0f} บาท " f"แต่มีเพียง {self.balance:,.0f} บาท" ) self.balance -= amount return f"✅ ถอน {amount:,.0f} บาท สำเร็จ คงเหลือ {self.balance:,.0f} บาท" except (InvalidAmountError, InsufficientFundsError, AccountLockedError, ValueError) as e: return f"❌ {e}" def _verify_pin(self, pin): """ตรวจสอบ PIN (สมมติ PIN คือ 1234)""" return pin == "1234" def transfer(self, to_account, amount, pin): """โอนเงิน""" try: # ถอนจากบัญชีต้นทาง result = self.withdraw(amount, pin) if "❌" in result: return result # ฝากเข้าบัญชีปลายทาง to_account.deposit(amount) return f"✅ โอน {amount:,.0f} บาท ไปยัง {to_account.account_no} สำเร็จ" except Exception as e: return f"❌ การโอนล้มเหลว: {e}" # ทดสอบ def test_bank_system(): # สร้างบัญชี acc1 = BankAccount("001", "สมชาย", 10000) acc2 = BankAccount("002", "สมหญิง", 5000) print("=== ทดสอบระบบธนาคาร ===\n") # Test 1: ฝากเงิน print("1. ทดสอบฝากเงิน:") print(acc1.deposit(5000)) print(acc1.deposit(-100)) # Error: จำนวนเงินไม่ถูกต้อง print() # Test 2: ถอนเงิน print("2. ทดสอบถอนเงิน:") print(acc1.withdraw(3000, "1234")) # สำเร็จ print(acc1.withdraw(20000, "1234")) # Error: เงินไม่พอ print() # Test 3: PIN ผิด print("3. ทดสอบ PIN ผิด:") print(acc1.withdraw(1000, "0000")) # PIN ผิด ครั้งที่ 1 print(acc1.withdraw(1000, "1111")) # PIN ผิด ครั้งที่ 2 print(acc1.withdraw(1000, "9999")) # PIN ผิด ครั้งที่ 3 → ล็อคบัญชี print(acc1.withdraw(1000, "1234")) # บัญชีถูกล็อค print() # Test 4: โอนเงิน print("4. ทดสอบโอนเงิน:") acc3 = BankAccount("003", "สมศรี", 20000) print(acc3.transfer(acc2, 5000, "1234")) print(f"บัญชีต้นทาง ({acc3.account_no}): {acc3.balance:,.0f} บาท") print(f"บัญชีปลายทาง ({acc2.account_no}): {acc2.balance:,.0f} บาท") if __name__ == "__main__": test_bank_system()

📝 Homework - วันที่ 1

โจทย์: สร้างระบบจัดการสินค้าคงคลัง (Inventory System) แบบ OOP

ความต้องการ:

  • Class Product: เก็บข้อมูลสินค้า (รหัส, ชื่อ, ราคา, จำนวน)
  • Class Inventory: จัดการรายการสินค้าทั้งหมด
  • ฟีเจอร์: เพิ่ม, ลบ, แก้ไข, ค้นหา สินค้า
  • ตรวจสอบ stock ต่ำกว่าที่กำหนด (Low Stock Alert)
  • คำนวณมูลค่ารวมของสินค้าคงคลัง
  • มี Error Handling ครบทุก function

📅 วันที่ 2: Web Development with HTML/CSS/Python (7 ธ.ค. - ONSITE)

🌅 ช่วงเช้า (08:30-12:00)

2.1 HTML Essentials

1.5 ชั่วโมง Frontend

🌐 ทำความเข้าใจ HTML

HTML (HyperText Markup Language) คือภาษาที่ใช้สร้างโครงสร้างหน้าเว็บ

1. โครงสร้าง HTML5 พื้นฐาน

<!DOCTYPE html> <html lang="th"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>เว็บไซต์แรกของฉัน</title> </head> <body> <h1>สวัสดีครับ</h1> <p>นี่คือหน้าเว็บแรกของฉัน</p> </body> </html>

2. Tags สำคัญที่ต้องรู้

<!-- Headings --> <h1>หัวข้อใหญ่สุด</h1> <h2>หัวข้อรอง</h2> <h3>หัวข้อย่อย</h3> <!-- Paragraph --> <p>ข้อความทั่วไป</p> <!-- Links --> <a href="https://www.google.com">ไปที่ Google</a> <!-- Images --> <img src="image.jpg" alt="รูปภาพ"> <!-- Lists --> <ul> <li>รายการที่ 1</li> <li>รายการที่ 2</li> </ul> <ol> <li>ขั้นตอนที่ 1</li> <li>ขั้นตอนที่ 2</li> </ol> <!-- Division (Container) --> <div class="container"> <p>เนื้อหาในกล่อง</p> </div> <!-- Span (Inline) --> <p>ข้อความ <span class="highlight">ที่เน้น</span> บางส่วน</p>

3. Forms (ฟอร์มรับข้อมูล)

<form action="/submit" method="POST"> <!-- Text Input --> <label for="name">ชื่อ:</label> <input type="text" id="name" name="name" required> <!-- Email Input --> <label for="email">อีเมล:</label> <input type="email" id="email" name="email" required> <!-- Password --> <label for="password">รหัสผ่าน:</label> <input type="password" id="password" name="password"> <!-- Number --> <label for="age">อายุ:</label> <input type="number" id="age" name="age" min="1" max="100"> <!-- Select Dropdown --> <label for="department">แผนก:</label> <select id="department" name="department"> <option value="sales">ฝ่ายขาย</option> <option value="it">ฝ่าย IT</option> <option value="hr">ฝ่ายบุคคล</option> </select> <!-- Radio Button --> <label>เพศ:</label> <input type="radio" id="male" name="gender" value="male"> <label for="male">ชาย</label> <input type="radio" id="female" name="gender" value="female"> <label for="female">หญิง</label> <!-- Checkbox --> <input type="checkbox" id="agree" name="agree"> <label for="agree">ยอมรับเงื่อนไข</label> <!-- Textarea --> <label for="message">ข้อความ:</label> <textarea id="message" name="message" rows="4"></textarea> <!-- Submit Button --> <button type="submit">ส่งข้อมูล</button> </form>

4. Table (ตาราง)

<table> <thead> <tr> <th>รหัส</th> <th>ชื่อพนักงาน</th> <th>แผนก</th> <th>เงินเดือน</th> </tr> </thead> <tbody> <tr> <td>E001</td> <td>สมชาย</td> <td>ฝ่ายขาย</td> <td>30,000</td> </tr> <tr> <td>E002</td> <td>สมหญิง</td> <td>ฝ่ายบัญชี</td> <td>35,000</td> </tr> </tbody> </table>

5. Semantic HTML5

ใช้ Tag ที่บ่งบอกความหมายชัดเจน ช่วย SEO และอ่านง่าย

<header> <nav> <ul> <li><a href="#home">หน้าแรก</a></li> <li><a href="#about">เกี่ยวกับเรา</a></li> <li><a href="#contact">ติดต่อเรา</a></li> </ul> </nav> </header> <main> <section id="home"> <h1>ยินดีต้อนรับ</h1> <p>เนื้อหาหลัก</p> </section> <article> <h2>บทความ</h2> <p>เนื้อหาบทความ</p> </article> <aside> <h3>Sidebar</h3> <p>เนื้อหาเสริม</p> </aside> </main> <footer> <p>© 2024 บริษัทของเรา</p> </footer>
ตัวอย่าง

💡 สร้างฟอร์มลงทะเบียนพนักงาน

<!DOCTYPE html> <html lang="th"> <head> <meta charset="UTF-8"> <title>ลงทะเบียนพนักงาน</title> </head> <body> <h1>📝 แบบฟอร์มลงทะเบียนพนักงาน</h1> <form action="/register" method="POST"> <fieldset> <legend>ข้อมูลส่วนตัว</legend> <label for="firstname">ชื่อ: *</label> <input type="text" id="firstname" name="firstname" required> <label for="lastname">นามสกุล: *</label> <input type="text" id="lastname" name="lastname" required> <label for="email">อีเมล: *</label> <input type="email" id="email" name="email" required> <label for="phone">เบอร์โทร:</label> <input type="tel" id="phone" name="phone" pattern="[0-9]{10}"> <label for="birthdate">วันเกิด:</label> <input type="date" id="birthdate" name="birthdate"> <label>เพศ:</label> <input type="radio" id="male" name="gender" value="male"> <label for="male">ชาย</label> <input type="radio" id="female" name="gender" value="female"> <label for="female">หญิง</label> </fieldset> <fieldset> <legend>ข้อมูลการทำงาน</legend> <label for="empid">รหัสพนักงาน:</label> <input type="text" id="empid" name="empid"> <label for="department">แผนก:</label> <select id="department" name="department"> <option value="">-- เลือกแผนก --</option> <option value="sales">ฝ่ายขาย</option> <option value="it">ฝ่าย IT</option> <option value="hr">ฝ่ายบุคคล</option> <option value="finance">ฝ่ายการเงิน</option> </select> <label for="position">ตำแหน่ง:</label> <input type="text" id="position" name="position"> <label for="salary">เงินเดือน:</label> <input type="number" id="salary" name="salary" min="15000"> <label for="startdate">วันที่เริ่มงาน:</label> <input type="date" id="startdate" name="startdate"> </fieldset> <button type="submit">ส่งข้อมูล</button> <button type="reset">ล้างข้อมูล</button> </form> </body> </html>

2.2 CSS Fundamentals

1.5 ชั่วโมง Styling

🎨 ทำความเข้าใจ CSS

CSS (Cascading Style Sheets) ใช้สำหรับตกแต่งหน้าเว็บให้สวยงาม

1. การเชื่อมต่อ CSS กับ HTML

<!-- 1. Inline CSS --> <p style="color: red; font-size: 20px;">ข้อความสีแดง</p> <!-- 2. Internal CSS --> <head> <style> p { color: blue; font-size: 16px; } </style> </head> <!-- 3. External CSS (แนะนำ) --> <head> <link rel="stylesheet" href="styles.css"> </head>

2. Selectors (ตัวเลือก)

/* Element Selector */ p { color: black; } /* Class Selector */ .highlight { background-color: yellow; } /* ID Selector */ #header { font-size: 24px; } /* Multiple Selectors */ h1, h2, h3 { font-family: Arial, sans-serif; } /* Descendant Selector */ div p { margin: 10px; } /* Child Selector */ div > p { padding: 5px; } /* Pseudo-classes */ a:hover { color: red; } button:active { transform: scale(0.95); }

3. Box Model

.box { /* Content */ width: 300px; height: 200px; /* Padding (ระยะห่างด้านใน) */ padding: 20px; /* หรือกำหนดแยก */ padding-top: 10px; padding-right: 15px; padding-bottom: 10px; padding-left: 15px; /* Border (กรอบ) */ border: 2px solid #333; border-radius: 10px; /* Margin (ระยะห่างด้านนอก) */ margin: 20px auto; /* หรือกำหนดแยก */ margin-top: 20px; margin-right: auto; margin-bottom: 20px; margin-left: auto; }

4. Flexbox (จัดเรียงแบบยืดหยุ่น)

/* Container */ .container { display: flex; /* จัดเรียงในแนวนอน (default) */ flex-direction: row; /* หรือ column สำหรับแนวตั้ง */ /* จัดเรียงแนวนอน */ justify-content: center; /* flex-start, flex-end, space-between, space-around */ /* จัดเรียงแนวตั้ง */ align-items: center; /* flex-start, flex-end, stretch */ /* ให้ขึ้นบรรทัดใหม่ถ้าไม่พอ */ flex-wrap: wrap; /* ระยะห่างระหว่าง item */ gap: 20px; } /* Items */ .item { flex: 1; /* ขยายเต็มพื้นที่ */ /* หรือ */ flex-grow: 1; flex-shrink: 1; flex-basis: auto; }

5. Grid (จัดเรียงแบบตาราง)

.grid-container { display: grid; /* กำหนดจำนวนคอลัมน์ */ grid-template-columns: 1fr 1fr 1fr; /* 3 คอลัมน์เท่ากัน */ /* หรือ */ grid-template-columns: 200px auto 200px; /* หรือ */ grid-template-columns: repeat(3, 1fr); /* กำหนดจำนวนแถว */ grid-template-rows: 100px auto 100px; /* ระยะห่าง */ gap: 20px; /* หรือกำหนดแยก */ column-gap: 20px; row-gap: 10px; } .grid-item { /* กำหนดขอบเขต */ grid-column: 1 / 3; /* ครอบคลุม 2 คอลัมน์ */ grid-row: 1 / 2; }

6. Responsive Design

/* Mobile First Approach */ .container { width: 100%; padding: 10px; } /* Tablet */ @media (min-width: 768px) { .container { width: 750px; margin: 0 auto; } } /* Desktop */ @media (min-width: 1024px) { .container { width: 960px; } } /* Large Desktop */ @media (min-width: 1200px) { .container { width: 1140px; } }
Workshop

🔨 Workshop: ออกแบบหน้า Login ที่สวยงาม

สร้างหน้า Login ที่มี:

  • การ์ดตรงกลางหน้าจอ
  • Gradient Background
  • Form Validation Styles
  • Hover Effects
  • Responsive Design

HTML:

<!DOCTYPE html> <html lang="th"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Login</title> <link rel="stylesheet" href="login.css"> </head> <body> <div class="container"> <div class="login-card"> <div class="login-header"> <h1>🔐 เข้าสู่ระบบ</h1> <p>ยินดีต้อนรับกลับมา</p> </div> <form class="login-form"> <div class="form-group"> <label for="username">ชื่อผู้ใช้</label> <input type="text" id="username" placeholder="กรอกชื่อผู้ใช้" required> </div> <div class="form-group"> <label for="password">รหัสผ่าน</label> <input type="password" id="password" placeholder="กรอกรหัสผ่าน" required> </div> <div class="form-group checkbox"> <input type="checkbox" id="remember"> <label for="remember">จดจำฉันไว้</label> </div> <button type="submit" class="btn-login">เข้าสู่ระบบ</button> <div class="form-footer"> <a href="#">ลืมรหัสผ่าน?</a> <a href="#">สร้างบัญชีใหม่</a> </div> </form> </div> </div> </body> </html>

CSS (login.css):

* { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; display: flex; justify-content: center; align-items: center; } .container { width: 100%; padding: 20px; } .login-card { max-width: 400px; margin: 0 auto; background: white; border-radius: 20px; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); overflow: hidden; } .login-header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 40px 30px; text-align: center; } .login-header h1 { font-size: 28px; margin-bottom: 10px; } .login-header p { opacity: 0.9; font-size: 14px; } .login-form { padding: 30px; } .form-group { margin-bottom: 20px; } .form-group label { display: block; margin-bottom: 8px; color: #333; font-weight: 500; } .form-group input[type="text"], .form-group input[type="password"] { width: 100%; padding: 12px 15px; border: 2px solid #e1e1e1; border-radius: 8px; font-size: 14px; transition: all 0.3s; } .form-group input:focus { outline: none; border-color: #667eea; box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1); } .form-group.checkbox { display: flex; align-items: center; } .form-group.checkbox input { width: auto; margin-right: 8px; } .btn-login { width: 100%; padding: 14px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border: none; border-radius: 8px; font-size: 16px; font-weight: 600; cursor: pointer; transition: transform 0.2s, box-shadow 0.3s; } .btn-login:hover { transform: translateY(-2px); box-shadow: 0 10px 20px rgba(102, 126, 234, 0.4); } .btn-login:active { transform: translateY(0); } .form-footer { margin-top: 20px; display: flex; justify-content: space-between; font-size: 14px; } .form-footer a { color: #667eea; text-decoration: none; } .form-footer a:hover { text-decoration: underline; } /* Responsive */ @media (max-width: 480px) { .login-card { border-radius: 0; } .login-header { padding: 30px 20px; } .login-form { padding: 20px; } }

🌆 ช่วงบ่าย (13:00-17:00)

2.3 Python for Web - CGI & HTTP

1 ชั่วโมง Web Fundamentals

🌐 HTTP - ภาษาของเว็บ

HTTP Methods

  • GET: ดึงข้อมูล (เช่น เปิดหน้าเว็บ, ค้นหา)
  • POST: ส่งข้อมูล (เช่น ส่งฟอร์ม, อัพโหลดไฟล์)
  • PUT: แก้ไขข้อมูล (Update)
  • DELETE: ลบข้อมูล

Request/Response Cycle

# ตัวอย่าง HTTP Request GET /products?category=electronics HTTP/1.1 Host: www.example.com User-Agent: Mozilla/5.0 Accept: text/html # HTTP Response HTTP/1.1 200 OK Content-Type: text/html Content-Length: 1234 <html> <body> <h1>สินค้าอิเล็กทรอนิกส์</h1> </body> </html>
ตัวอย่าง

💡 สร้าง Simple HTTP Server ด้วย Python

# simple_server.py from http.server import HTTPServer, BaseHTTPRequestHandler import json class MyHandler(BaseHTTPRequestHandler): def do_GET(self): """จัดการ GET Request""" if self.path == '/': self.send_response(200) self.send_header('Content-type', 'text/html; charset=utf-8') self.end_headers() html = ''' <!DOCTYPE html> <html> <head><meta charset="utf-8"></head> <body> <h1>สวัสดีจาก Python Server</h1> <p>Server กำลังทำงาน!</p> </body> </html> ''' self.wfile.write(html.encode()) elif self.path == '/api/products': self.send_response(200) self.send_header('Content-type', 'application/json') self.end_headers() products = [ {"id": 1, "name": "โน้ตบุ๊ค", "price": 25000}, {"id": 2, "name": "เมาส์", "price": 500}, {"id": 3, "name": "คีย์บอร์ด", "price": 1200} ] self.wfile.write(json.dumps(products, ensure_ascii=False).encode()) if __name__ == '__main__': server = HTTPServer(('localhost', 8000), MyHandler) print("Server running on http://localhost:8000") server.serve_forever()

2.4 การเชื่อมต่อ Python กับ HTML/CSS

2 ชั่วโมง Integration

Template Rendering

# app.py from http.server import HTTPServer, BaseHTTPRequestHandler from string import Template class ProductHandler(BaseHTTPRequestHandler): def do_GET(self): # อ่าน Template with open('template.html', 'r', encoding='utf-8') as f: template = Template(f.read()) # ข้อมูล products = [ {"name": "โน้ตบุ๊ค", "price": 25000, "stock": 5}, {"name": "เมาส์", "price": 500, "stock": 20}, {"name": "คีย์บอร์ด", "price": 1200, "stock": 15} ] # สร้าง HTML สำหรับสินค้า product_html = "" for p in products: product_html += f''' <tr> <td>{p['name']}</td> <td>{p['price']:,} บาท</td> <td>{p['stock']}</td> </tr> ''' # แทนค่าใน Template html = template.substitute(products=product_html) self.send_response(200) self.send_header('Content-type', 'text/html; charset=utf-8') self.end_headers() self.wfile.write(html.encode())

template.html:

<!DOCTYPE html> <html> <head> <title>รายการสินค้า</title> <style> table { border-collapse: collapse; width: 100%; } th, td { padding: 10px; text-align: left; border: 1px solid #ddd; } th { background: #667eea; color: white; } </style> </head> <body> <h1>รายการสินค้า</h1> <table> <thead> <tr> <th>สินค้า</th> <th>ราคา</th> <th>คงเหลือ</th> </tr> </thead> <tbody> $products </tbody> </table> </body> </html>
Workshop

🔨 Project: ระบบแสดงรายการสินค้าพร้อมค้นหา

# product_system.py from http.server import HTTPServer, BaseHTTPRequestHandler from urllib.parse import urlparse, parse_qs import json products_db = [ {"id": 1, "name": "โน้ตบุ๊ค Dell", "category": "computer", "price": 25000, "stock": 5}, {"id": 2, "name": "เมาส์ Logitech", "category": "accessory", "price": 500, "stock": 20}, {"id": 3, "name": "คีย์บอร์ด Mechanical", "category": "accessory", "price": 1200, "stock": 15}, {"id": 4, "name": "Monitor LG 24\"", "category": "computer", "price": 4500, "stock": 8}, ] class ProductServer(BaseHTTPRequestHandler): def do_GET(self): parsed_path = urlparse(self.path) if parsed_path.path == '/': self.serve_html() elif parsed_path.path == '/api/search': self.search_products(parsed_path.query) elif parsed_path.path == '/styles.css': self.serve_css() def serve_html(self): html = ''' <!DOCTYPE html> <html lang="th"> <head> <meta charset="UTF-8"> <title>ระบบค้นหาสินค้า</title> <link rel="stylesheet" href="/styles.css"> </head> <body> <div class="container"> <h1>🛍️ ระบบค้นหาสินค้า</h1> <div class="search-box"> <input type="text" id="searchInput" placeholder="ค้นหาสินค้า..."> <select id="categoryFilter"> <option value="">ทุกหมวดหมู่</option> <option value="computer">คอมพิวเตอร์</option> <option value="accessory">อุปกรณ์เสริม</option> </select> <button onclick="searchProducts()">ค้นหา</button> </div> <div id="results"></div> </div> <script> function searchProducts() { const keyword = document.getElementById('searchInput').value; const category = document.getElementById('categoryFilter').value; fetch(`/api/search?keyword=${keyword}&category=${category}`) .then(res => res.json()) .then(data => { displayResults(data); }); } function displayResults(products) { const container = document.getElementById('results'); if (products.length === 0) { container.innerHTML = '<p>ไม่พบสินค้า</p>'; return; } let html = '<div class="product-grid">'; products.forEach(p => { html += ` <div class="product-card"> <h3>${p.name}</h3> <p class="category">${p.category}</p> <p class="price">${p.price.toLocaleString()} บาท</p> <p class="stock">คงเหลือ: ${p.stock} ชิ้น</p> </div> `; }); html += '</div>'; container.innerHTML = html; } // Load all products on start searchProducts(); </script> </body> </html> ''' self.send_response(200) self.send_header('Content-type', 'text/html; charset=utf-8') self.end_headers() self.wfile.write(html.encode()) def search_products(self, query_string): params = parse_qs(query_string) keyword = params.get('keyword', [''])[0].lower() category = params.get('category', [''])[0] results = products_db if keyword: results = [p for p in results if keyword in p['name'].lower()] if category: results = [p for p in results if p['category'] == category] self.send_response(200) self.send_header('Content-type', 'application/json') self.end_headers() self.wfile.write(json.dumps(results, ensure_ascii=False).encode()) if __name__ == '__main__': server = HTTPServer(('localhost', 8000), ProductServer) print("Server: http://localhost:8000") server.serve_forever()

2.5 เตรียมความพร้อมสู่ Django

1 ชั่วโมง

🤔 ทำไมต้องใช้ Web Framework?

  • เขียนโค้ดซ้ำน้อยลง (Routing, Authentication, Database)
  • มี Security Features ในตัว
  • มีโครงสร้างที่เป็นมาตรฐาน
  • Community ใหญ่ มี Library เยอะ

Django Architecture: MTV Pattern

  • Model: จัดการฐานข้อมูล
  • Template: ไฟล์ HTML
  • View: Logic ประมวลผล

ติดตั้ง Django

# สร้าง Virtual Environment python -m venv django_env django_env\Scripts\activate # Windows source django_env/bin/activate # Mac/Linux # ติดตั้ง Django pip install django # ตรวจสอบ python -m django --version # สร้าง Project django-admin startproject myproject cd myproject # รัน Server python manage.py runserver # เปิดเบราว์เซอร์: http://127.0.0.1:8000

📝 Assignment - วันที่ 2

  • ติดตั้ง Django บนเครื่องของคุณ
  • สร้าง Django Project ชื่อ "blog_project"
  • รัน Server และถ่ายภาพหน้าจอมาส่ง
  • ศึกษาโครงสร้างไฟล์ของ Django Project

📅 วันที่ 3: Django Framework Deep Dive (13 ธ.ค. - ONLINE)

🌅 ช่วงเช้า (08:30-12:00)

3.1 Django Setup & Project Structure

1 ชั่วโมง

โครงสร้าง Django Project

myproject/ ├── manage.py # คำสั่งจัดการโปรเจค ├── myproject/ # โฟลเดอร์หลัก │ ├── __init__.py │ ├── settings.py # การตั้งค่า │ ├── urls.py # URL Routing │ ├── asgi.py │ └── wsgi.py

สร้าง Django App

# สร้าง App python manage.py startapp blog # โครงสร้าง App blog/ ├── __init__.py ├── admin.py # Admin Interface ├── apps.py # App Configuration ├── models.py # Database Models ├── views.py # Views (Logic) ├── urls.py # URL Routing (สร้างเอง) ├── tests.py # Tests └── migrations/ # Database Migrations

เพิ่ม App ใน Settings

# myproject/settings.py INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'blog', # เพิ่ม App ของเรา ]
Demo

💡 สร้าง Blog Project

# 1. สร้าง Project django-admin startproject blog_project cd blog_project # 2. สร้าง App python manage.py startapp posts # 3. เพิ่ม App ใน settings.py # blog_project/settings.py INSTALLED_APPS = [ ... 'posts', ] # 4. สร้าง View แรก # posts/views.py from django.http import HttpResponse def index(request): return HttpResponse("สวัสดี! นี่คือ Blog ของฉัน") # 5. สร้าง URL # posts/urls.py (สร้างไฟล์ใหม่) from django.urls import path from . import views urlpatterns = [ path('', views.index, name='index'), ] # 6. เชื่อม URL กับ Project # blog_project/urls.py from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('', include('posts.urls')), ] # 7. รัน Server python manage.py runserver

3.2 Views & Templates

2 ชั่วโมง

Function-Based Views (FBV)

# posts/views.py from django.shortcuts import render from django.http import HttpResponse def home(request): """หน้าแรก""" return render(request, 'posts/home.html') def post_list(request): """รายการบทความ""" posts = [ {'title': 'บทความที่ 1', 'content': 'เนื้อหา...'}, {'title': 'บทความที่ 2', 'content': 'เนื้อหา...'}, ] context = {'posts': posts} return render(request, 'posts/post_list.html', context) def post_detail(request, post_id): """รายละเอียดบทความ""" # ดึงข้อมูลจาก Database (เรียนในหัวข้อถัดไป) post = {'id': post_id, 'title': f'บทความที่ {post_id}'} return render(request, 'posts/detail.html', {'post': post})

Django Template Language (DTL)

<!-- posts/templates/posts/post_list.html --> <!DOCTYPE html> <html> <head> <title>รายการบทความ</title> </head> <body> <h1>บทความทั้งหมด</h1> {% if posts %} {% for post in posts %} <article> <h2>{{ post.title }}</h2> <p>{{ post.content }}</p> <a href="{% url 'post_detail' post.id %}">อ่านเพิ่มเติม</a> </article> {% endfor %} {% else %} <p>ยังไม่มีบทความ</p> {% endif %} </body> </html>

Template Inheritance (สืบทอด Template)

<!-- templates/base.html --> <!DOCTYPE html> <html lang="th"> <head> <meta charset="UTF-8"> <title>{% block title %}My Blog{% endblock %}</title> <style> body { font-family: Arial; margin: 0; padding: 0; } nav { background: #333; color: white; padding: 10px; } .container { padding: 20px; } </style> </head> <body> <nav> <a href="{% url 'home' %}">หน้าแรก</a> <a href="{% url 'post_list' %}">บทความ</a> </nav> <div class="container"> {% block content %} {% endblock %} </div> <footer> <p>© 2024 My Blog</p> </footer> </body> </html> <!-- posts/templates/posts/home.html --> {% extends 'base.html' %} {% block title %}หน้าแรก - My Blog{% endblock %} {% block content %} <h1>ยินดีต้อนรับสู่ Blog ของฉัน</h1> <p>ที่นี่มีบทความดีๆ มากมาย</p> {% endblock %}
Workshop

🔨 สร้างระบบ CRUD พื้นฐาน (Blog Posts)

สร้างระบบจัดการบทความที่มี:

  • แสดงรายการบทความ (List)
  • แสดงรายละเอียด (Detail)
  • เพิ่มบทความ (Create)
  • แก้ไขบทความ (Update)
  • ลบบทความ (Delete)

🌆 ช่วงบ่าย (13:00-17:00)

3.3 Models & Database

2 ชั่วโมง

สร้าง Model

# posts/models.py from django.db import models from django.contrib.auth.models import User class Category(models.Model): """หมวดหมู่""" name = models.CharField(max_length=100) slug = models.SlugField(unique=True) created_at = models.DateTimeField(auto_now_add=True) class Meta: verbose_name_plural = "Categories" def __str__(self): return self.name class Post(models.Model): """บทความ""" STATUS_CHOICES = [ ('draft', 'แบบร่าง'), ('published', 'เผยแพร่'), ] title = models.CharField(max_length=200) slug = models.SlugField(unique=True) author = models.ForeignKey(User, on_delete=models.CASCADE) category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True) content = models.TextField() status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft') views = models.IntegerField(default=0) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: ordering = ['-created_at'] def __str__(self): return self.title class Comment(models.Model): """ความคิดเห็น""" post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments') author = models.CharField(max_length=100) email = models.EmailField() content = models.TextField() created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return f'Comment by {self.author} on {self.post}'

Migrations

# สร้าง Migration files python manage.py makemigrations # ดู SQL ที่จะรัน python manage.py sqlmigrate posts 0001 # รัน Migrations python manage.py migrate # ดู Migrations ทั้งหมด python manage.py showmigrations
Workshop

🔨 สร้างฐานข้อมูล E-commerce

# shop/models.py from django.db import models class Category(models.Model): name = models.CharField(max_length=100) description = models.TextField(blank=True) def __str__(self): return self.name class Product(models.Model): category = models.ForeignKey(Category, on_delete=models.CASCADE) name = models.CharField(max_length=200) sku = models.CharField(max_length=50, unique=True) description = models.TextField() price = models.DecimalField(max_digits=10, decimal_places=2) stock = models.IntegerField(default=0) image = models.ImageField(upload_to='products/', blank=True) created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return self.name class Customer(models.Model): first_name = models.CharField(max_length=100) last_name = models.CharField(max_length=100) email = models.EmailField(unique=True) phone = models.CharField(max_length=20) address = models.TextField() def __str__(self): return f"{self.first_name} {self.last_name}" class Order(models.Model): STATUS_CHOICES = [ ('pending', 'รอดำเนินการ'), ('processing', 'กำลังจัดส่ง'), ('completed', 'สำเร็จ'), ('cancelled', 'ยกเลิก'), ] customer = models.ForeignKey(Customer, on_delete=models.CASCADE) status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending') total_amount = models.DecimalField(max_digits=10, decimal_places=2) created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return f"Order #{self.id} by {self.customer}" class OrderItem(models.Model): order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name='items') product = models.ForeignKey(Product, on_delete=models.CASCADE) quantity = models.IntegerField() price = models.DecimalField(max_digits=10, decimal_places=2) def __str__(self): return f"{self.quantity}x {self.product.name}"

3.4 Django Admin

1 ชั่วโมง

Register Models

# posts/admin.py from django.contrib import admin from .models import Category, Post, Comment # วิธีที่ 1: แบบง่าย admin.site.register(Category) # วิธีที่ 2: Customize Admin @admin.register(Post) class PostAdmin(admin.ModelAdmin): list_display = ['title', 'author', 'category', 'status', 'views', 'created_at'] list_filter = ['status', 'category', 'created_at'] search_fields = ['title', 'content'] prepopulated_fields = {'slug': ('title',)} date_hierarchy = 'created_at' ordering = ['-created_at'] # Inline Comments class CommentInline(admin.TabularInline): model = Comment extra = 0 inlines = [CommentInline] @admin.register(Comment) class CommentAdmin(admin.ModelAdmin): list_display = ['author', 'post', 'created_at'] list_filter = ['created_at'] search_fields = ['author', 'content']

สร้าง Superuser

# สร้าง Admin User python manage.py createsuperuser # กรอกข้อมูล Username: admin Email: admin@example.com Password: ******** # เข้าสู่ระบบ http://127.0.0.1:8000/admin/

3.5 QuerySet & Database Operations

1 ชั่วโมง

CRUD Operations

# Create post = Post.objects.create( title="บทความใหม่", slug="new-post", content="เนื้อหา...", author=request.user ) # Read (Single) post = Post.objects.get(id=1) post = Post.objects.get(slug='new-post') # Read (Multiple) posts = Post.objects.all() published = Post.objects.filter(status='published') latest = Post.objects.filter(status='published')[:5] # Update post = Post.objects.get(id=1) post.title = "แก้ไขชื่อ" post.save() # หรือ Post.objects.filter(id=1).update(title="แก้ไขชื่อ") # Delete post = Post.objects.get(id=1) post.delete() # หรือ Post.objects.filter(id=1).delete()

Filtering & Ordering

# Filter Post.objects.filter(status='published') Post.objects.filter(views__gte=100) # views >= 100 Post.objects.filter(title__contains='Django') Post.objects.filter(created_at__year=2024) # Exclude Post.objects.exclude(status='draft') # Order Post.objects.order_by('-created_at') # ใหม่สุดก่อน Post.objects.order_by('title') # Limit Post.objects.all()[:10] # 10 รายการแรก # Count Post.objects.filter(status='published').count() # Exists Post.objects.filter(slug='test').exists()
Practice

🔨 Query ข้อมูลขายดีประจำเดือน

from django.db.models import Sum, Count, Avg from datetime import datetime, timedelta # สินค้าขายดีในเดือนนี้ this_month = datetime.now().replace(day=1) next_month = (this_month + timedelta(days=32)).replace(day=1) top_products = OrderItem.objects.filter( order__created_at__gte=this_month, order__created_at__lt=next_month, order__status='completed' ).values('product__name').annotate( total_quantity=Sum('quantity'), total_revenue=Sum('price') ).order_by('-total_quantity')[:10] # ยอดขายรวมประจำเดือน monthly_revenue = Order.objects.filter( created_at__gte=this_month, created_at__lt=next_month, status='completed' ).aggregate(total=Sum('total_amount')) print(f"ยอดขายเดือนนี้: {monthly_revenue['total']:,.2f} บาท")

📅 วันที่ 4: Advanced Django & Final Project (14 ธ.ค. - ONLINE)

🌅 ช่วงเช้า (08:30-12:00)

4.1 Forms & Validation

1.5 ชั่วโมง

Django Forms

# posts/forms.py from django import forms from .models import Post, Comment class PostForm(forms.ModelForm): class Meta: model = Post fields = ['title', 'slug', 'category', 'content', 'status'] widgets = { 'title': forms.TextInput(attrs={'class': 'form-control'}), 'slug': forms.TextInput(attrs={'class': 'form-control'}), 'content': forms.Textarea(attrs={'class': 'form-control', 'rows': 10}), } def clean_title(self): """Custom validation""" title = self.cleaned_data['title'] if len(title) < 10: raise forms.ValidationError("ชื่อต้องมีอย่างน้อย 10 ตัวอักษร") return title class CommentForm(forms.Form): author = forms.CharField(max_length=100, label="ชื่อ") email = forms.EmailField(label="อีเมล") content = forms.CharField(widget=forms.Textarea, label="ความคิดเห็น") def clean_content(self): content = self.cleaned_data['content'] if len(content) < 10: raise forms.ValidationError("ความคิดเห็นสั้นเกินไป") return content

ใช้งาน Forms ใน Views

# posts/views.py from django.shortcuts import render, redirect from .forms import PostForm, CommentForm from .models import Post def create_post(request): if request.method == 'POST': form = PostForm(request.POST) if form.is_valid(): post = form.save(commit=False) post.author = request.user post.save() return redirect('post_detail', slug=post.slug) else: form = PostForm() return render(request, 'posts/create.html', {'form': form}) def edit_post(request, slug): post = Post.objects.get(slug=slug) if request.method == 'POST': form = PostForm(request.POST, instance=post) if form.is_valid(): form.save() return redirect('post_detail', slug=post.slug) else: form = PostForm(instance=post) return render(request, 'posts/edit.html', {'form': form, 'post': post})
ตัวอย่าง

💡 ฟอร์มลงทะเบียนลูกค้า

# forms.py from django import forms from .models import Customer class CustomerRegistrationForm(forms.ModelForm): password = forms.CharField(widget=forms.PasswordInput) confirm_password = forms.CharField(widget=forms.PasswordInput) class Meta: model = Customer fields = ['first_name', 'last_name', 'email', 'phone', 'address'] def clean_email(self): email = self.cleaned_data['email'] if Customer.objects.filter(email=email).exists(): raise forms.ValidationError("อีเมลนี้ถูกใช้แล้ว") return email def clean(self): cleaned_data = super().clean() password = cleaned_data.get('password') confirm = cleaned_data.get('confirm_password') if password != confirm: raise forms.ValidationError("รหัสผ่านไม่ตรงกัน") return cleaned_data # views.py def register(request): if request.method == 'POST': form = CustomerRegistrationForm(request.POST) if form.is_valid(): customer = form.save(commit=False) customer.set_password(form.cleaned_data['password']) customer.save() return redirect('login') else: form = CustomerRegistrationForm() return render(request, 'register.html', {'form': form})

4.2 User Authentication

1.5 ชั่วโมง

Login/Logout

# accounts/views.py from django.contrib.auth import authenticate, login, logout from django.shortcuts import render, redirect def user_login(request): if request.method == 'POST': username = request.POST['username'] password = request.POST['password'] user = authenticate(request, username=username, password=password) if user is not None: login(request, user) return redirect('home') else: return render(request, 'login.html', {'error': 'ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง'}) return render(request, 'login.html') def user_logout(request): logout(request) return redirect('home')

Registration

from django.contrib.auth.models import User from django.contrib.auth.forms import UserCreationForm def register(request): if request.method == 'POST': form = UserCreationForm(request.POST) if form.is_valid(): user = form.save() login(request, user) return redirect('home') else: form = UserCreationForm() return render(request, 'register.html', {'form': form})

Permissions & Authorization

# ใช้ Decorator from django.contrib.auth.decorators import login_required, permission_required @login_required def dashboard(request): return render(request, 'dashboard.html') @permission_required('posts.add_post') def create_post(request): # เฉพาะคนที่มีสิทธิ์ pass # ตรวจสอบใน Template {% if user.is_authenticated %}

สวัสดี {{ user.username }}

ออกจากระบบ {% else %} เข้าสู่ระบบ {% endif %}

🌆 ช่วงบ่าย (13:00-17:00)

4.3 Static Files & Media

1 ชั่วโมง

Static Files (CSS, JS, Images)

# settings.py STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static'), ] # โครงสร้างโฟลเดอร์ myproject/ ├── static/ │ ├── css/ │ │ └── style.css │ ├── js/ │ │ └── script.js │ └── images/ │ └── logo.png # ใช้ใน Template {% load static %} <link rel="stylesheet" href="{% static 'css/style.css' %}"> <script src="{% static 'js/script.js' %}"></script> <img src="{% static 'images/logo.png' %}"> # Collect Static (Production) python manage.py collectstatic

Media Files (User Uploads)

# settings.py MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media') # urls.py from django.conf import settings from django.conf.urls.static import static urlpatterns = [ # ... urls ] if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) # models.py class Product(models.Model): image = models.ImageField(upload_to='products/') # Template <img src="{{ product.image.url }}" alt="{{ product.name }}">

4.4 Final Project: ระบบร้านค้าออนไลน์

2.5 ชั่วโมง

🎯 เป้าหมาย Final Project

สร้างเว็บแอปพลิเคชันร้านค้าออนไลน์ที่ครบครัน

Features ที่ต้องมี

  • ✅ หน้าแสดงสินค้า (พร้อมรูปภาพ)
  • ✅ ระบบค้นหาและกรองสินค้า
  • ✅ รายละเอียดสินค้า
  • ✅ ตะกร้าสินค้า
  • ✅ ระบบสมาชิก (Login/Register)
  • ✅ Admin Panel จัดการสินค้า
  • ✅ Database ที่ออกแบบถูกต้อง
Final Project

🚀 โครงสร้าง Project

# 1. สร้าง Project django-admin startproject shop_project cd shop_project # 2. สร้าง Apps python manage.py startapp products python manage.py startapp cart python manage.py startapp orders # 3. ติดตั้ง Dependencies pip install Pillow # สำหรับจัดการรูปภาพ # 4. Models (products/models.py) class Category(models.Model): name = models.CharField(max_length=100) slug = models.SlugField(unique=True) def __str__(self): return self.name class Product(models.Model): category = models.ForeignKey(Category, on_delete=models.CASCADE) name = models.CharField(max_length=200) slug = models.SlugField(unique=True) description = models.TextField() price = models.DecimalField(max_digits=10, decimal_places=2) image = models.ImageField(upload_to='products/') stock = models.IntegerField(default=0) available = models.BooleanField(default=True) created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return self.name # 5. Views (products/views.py) def product_list(request): products = Product.objects.filter(available=True) categories = Category.objects.all() category_slug = request.GET.get('category') if category_slug: products = products.filter(category__slug=category_slug) search = request.GET.get('search') if search: products = products.filter(name__icontains=search) context = { 'products': products, 'categories': categories } return render(request, 'products/list.html', context) def product_detail(request, slug): product = Product.objects.get(slug=slug) return render(request, 'products/detail.html', {'product': product}) # 6. Cart Session def add_to_cart(request, product_id): product = Product.objects.get(id=product_id) cart = request.session.get('cart', {}) if str(product_id) in cart: cart[str(product_id)]['quantity'] += 1 else: cart[str(product_id)] = { 'name': product.name, 'price': str(product.price), 'quantity': 1 } request.session['cart'] = cart return redirect('cart_detail')

4.5 Deployment & Best Practices

30 นาที

Git Version Control

# สร้าง .gitignore *.pyc __pycache__/ db.sqlite3 /media /staticfiles .env # Git Commands git init git add . git commit -m "Initial commit" git remote add origin https://github.com/username/repo.git git push -u origin main

Environment Variables

# ติดตั้ง python-decouple pip install python-decouple # .env SECRET_KEY=your-secret-key-here DEBUG=False DATABASE_URL=postgresql://user:pass@localhost/dbname # settings.py from decouple import config SECRET_KEY = config('SECRET_KEY') DEBUG = config('DEBUG', default=False, cast=bool)

Security Best Practices

  • ตั้งค่า DEBUG = False ใน Production
  • ใช้ HTTPS
  • ตั้งค่า ALLOWED_HOSTS
  • ใช้ Environment Variables สำหรับข้อมูลสำคัญ
  • อัพเดท Dependencies เสมอ
  • ใช้ Strong Password Policy

Deployment Options

  • PythonAnywhere: ฟรี, ง่าย, เหมาะสำหรับเริ่มต้น
  • Heroku: ฟรีได้บ้าง, ใช้งานง่าย
  • DigitalOcean: เสียเงิน, ยืดหยุ่น
  • AWS/GCP: มืออาชีพ, มีเครื่องมือครบ

🎁 สิ่งที่ผู้เข้าอบรมจะได้รับ

1. 📄 ไฟล์เอกสาร

  • Slide ประกอบการสอนทุก Session (PDF)
  • Code ตัวอย่างครบทุก Workshop
  • Cheat Sheet Python & Django
  • E-book "Python for Beginners"
  • Django Quick Reference Guide

2. 💻 โปรเจคตัวอย่างจริง 5 ชุด

  • ระบบคำนวณเงินเดือน (Python Basics)
  • ระบบจัดการบัญชีธนาคาร (OOP)
  • ระบบแสดงสินค้า (Python + HTML/CSS)
  • Blog System (Django CRUD)
  • E-commerce Website (Final Project)

3. 🎯 ทักษะที่ได้

  • Python Programming (Basic to OOP)
  • Web Development (HTML/CSS)
  • Django Framework
  • Database Design & ORM
  • Authentication & Security
  • สามารถสร้างเว็บแอปพลิเคชันจริงได้

💡 จุดเด่นของหลักสูตรนี้

  • ✨ เน้นตัวอย่างจริงทุก Topic - ไม่มีทฤษฎีเปล่าๆ
  • ✨ Workshop ครบทุกวัน - ลงมือทำจริง เข้าใจจริง
  • ✨ Project ใกล้ชิดชีวิตจริง - นำไปใช้งานได้ทันที
  • ✨ รองรับทั้ง Onsite และ Online - เรียนแบบ Hybrid
  • ✨ มี Mentor ตอบคำถาม - ไม่ทิ้งไว้ข้างหลัง

พร้อมสร้างนักพัฒนาเว็บมืออาชีพในเวลา 4 วัน! 🚀

ติดต่อสอบถามเพิ่มเติม:

📞 โทร: 1506 กด 4

🌐 เว็บไซต์: www.dsd.go.th

📱 Facebook: สถาบันพัฒนาฝีมือแรงงาน 3 ชลบุรี