🚀 PHẦN 4: PHÁT TRIỂN WEB CHUYÊN NGHIỆP VỚI DJANGO
🎯 Mục tiêu tổng quát
- Hiểu rõ triết lý "Batteries-included" của Django.
- Nắm vững kiến trúc Model-View-Template (MVT).
- Sử dụng Django ORM để định nghĩa mô hình dữ liệu và tương tác với database một cách an toàn.
- Xây dựng các trang web động bằng Django Views và Templates.
- Tận dụng sức mạnh của Django Admin để quản lý dữ liệu mà không cần viết code.
- Sử dụng Django Forms để xử lý và xác thực dữ liệu từ người dùng một cách hiệu quả.
- Xây dựng lại ứng dụng từ Phần 3 trên nền tảng Django, sử dụng cơ sở dữ liệu thực sự thay vì file JSON.
🧑🏫 Bài 1: Giới thiệu Django và Cấu trúc MVT
Django là gì?
- Django là một web framework bậc cao, miễn phí và mã nguồn mở của Python.
- Triết lý "Batteries-included" (bao gồm sẵn pin): Cung cấp gần như mọi thứ bạn cần để xây dựng một ứng dụng web hoàn chỉnh (ORM, Admin, Authentication, Forms, Security...).
- Thúc đẩy việc phát triển nhanh, thiết kế sạch sẽ và thực dụng.
- Phù hợp cho các dự án lớn, phức tạp, yêu cầu tính bảo mật và khả năng mở rộng cao.
Kiến trúc Model-View-Template (MVT)
Django theo một biến thể của kiến trúc MVC (Model-View-Controller) gọi là MVT.
- Model: Định nghĩa cấu trúc dữ liệu, là cầu nối duy nhất và đáng tin cậy đến database. Nó không quan tâm dữ liệu sẽ được hiển thị như thế nào.
- View: Là nơi chứa logic xử lý. Nó nhận request, tương tác với Model để lấy dữ liệu, và quyết định Template nào sẽ được dùng để hiển thị dữ liệu đó.
- Template: Là lớp trình bày (presentation layer). Nó chỉ chịu trách nhiệm hiển thị dữ liệu nhận được từ View dưới dạng HTML.
Sơ đồ luồng xử lý trong Django:
(Internet)
|
V
(User's Browser sends a Request to a URL)
|
|
+---V--------------------------+
| DJANGO PROJECT |
| +--------------------+ |
| | urls.py (Router) | ----> Tìm URL phù hợp và gọi View tương ứng
| +--------------------+ |
| | |
| V |
| +--------------------+ |
| | Views.py | <---(3) View quyết định Template nào để render
| | (Logic xử lý) | ----(2) Gửi dữ liệu cho Template ---> +----------------+
| | | | | Template (.html)|
| +--|-----------------+ | (Hiển thị data)|
| | +-------^--------+
| +----(1) Tương tác với Model để lấy/lưu data ----+
| |
| +--------------------+ V
| | Models.py | <----------------> +-----------------+
| | (Cấu trúc data) | (Django ORM) | Database |
| +--------------------+ +-----------------+
| |
+--------------------------------------------------------------+Cài đặt và Tạo dự án Django đầu tiên
Cài đặt Django:
bashpip install djangoTạo một project:
bashdjango-admin startproject myproject .(Dấu
.để tạo project trong thư mục hiện tại). Cấu trúc thư mục sẽ là:textmyproject/ ├── myproject/ │ ├── __init__.py │ ├── asgi.py │ ├── settings.py <-- Cấu hình project │ ├── urls.py <-- Định tuyến URL chính │ └── wsgi.py └── manage.py <-- Công cụ dòng lệnh để quản lý projectTạo một app: Một project Django được tạo thành từ nhiều app, mỗi app đảm nhiệm một chức năng riêng.
bashpython manage.py startapp myappBây giờ cấu trúc sẽ có thêm thư mục
myapp.Đăng ký app: Mở
myproject/settings.pyvà thêmmyappvàoINSTALLED_APPS:pythonINSTALLED_APPS = [ # ... 'myapp.apps.MyappConfig', # Hoặc chỉ cần 'myapp' ]Chạy server:
bashpython manage.py runserverTruy cập
http://127.0.0.1:8000để xem trang chào mừng của Django.
🧑🏫 Bài 2: Django Models và ORM
Django Models là gì?
- Một model là một lớp Python kế thừa từ
django.db.models.Model. - Mỗi thuộc tính của lớp model đại diện cho một cột trong bảng cơ sở dữ liệu.
- Django sử dụng một công nghệ gọi là Object-Relational Mapping (ORM), cho phép bạn tương tác với database (SQL) bằng cách sử dụng code Python thay vì viết các câu lệnh SQL trực tiếp.
Tạo Model và Migration
Định nghĩa Model: Mở
myapp/models.pyvà định nghĩa model cho sản phẩm.python# myapp/models.py from django.db import models class Product(models.Model): name = models.CharField(max_length=200) price = models.DecimalField(max_digits=10, decimal_places=2) description = models.TextField(blank=True, null=True) # Có thể để trống created_at = models.DateTimeField(auto_now_add=True) # Tự động thêm ngày tạo def __str__(self): # Hiển thị tên sản phẩm trong Django Admin return self.nameTạo Migrations: Django sẽ so sánh model của bạn với database hiện tại và tạo ra một file "migration" mô tả những thay đổi cần thiết.
bashpython manage.py makemigrationsÁp dụng Migration: Lệnh này sẽ thực thi các file migration, tạo ra bảng
myapp_producttrong database.bashpython manage.py migrate(Mặc định Django sử dụng SQLite, một database đơn giản dựa trên file).
Tương tác với dữ liệu qua ORM Shell
Django cung cấp một shell tương tác đã nạp sẵn môi trường project của bạn.
python manage.py shellBên trong shell:
>>> from myapp.models import Product
# Tạo một đối tượng mới
>>> p1 = Product(name="Laptop XYZ", price=1200.50, description="Mẫu laptop mới nhất")
>>> p1.save()
# Lấy tất cả sản phẩm
>>> all_products = Product.objects.all()
>>> print(all_products)
<QuerySet [<Product: Laptop XYZ>]>
# Lọc sản phẩm
>>> specific_product = Product.objects.get(id=1)
>>> print(specific_product.name)
Laptop XYZ
# Cập nhật
>>> specific_product.price = 1150.00
>>> specific_product.save()
# Xóa
>>> specific_product.delete()🧑🏫 Bài 3: Django Views và Templates
Function-Based Views
View là một hàm Python nhận vào một đối tượng request và trả về một đối tượng response.
myapp/views.py:
from django.shortcuts import render
from .models import Product
def product_list(request):
# Sử dụng ORM để lấy tất cả sản phẩm, sắp xếp theo tên
products = Product.objects.all().order_by('name')
# Tạo một context dictionary để truyền dữ liệu tới template
context = {
'products': products,
'page_title': 'Danh sách sản phẩm'
}
# Render template và truyền context vào
return render(request, 'myapp/product_list.html', context)Django Template Language (DTL)
Rất giống với Jinja2 của Flask nhưng có một vài khác biệt nhỏ về cú pháp.
Tạo thư mục templates/myapp/ bên trong app myapp. myapp/templates/myapp/product_list.html:
<!DOCTYPE html>
<html>
<head>
<title>{{ page_title }}</title>
</head>
<body>
<h1>{{ page_title }}</h1>
{% if products %}
<ul>
<!-- Vòng lặp trong DTL -->
{% for product in products %}
<li>
{{ product.name }} - ${{ product.price }}
</li>
{% endfor %}
</ul>
{% else %}
<p>Không có sản phẩm nào.</p>
{% endif %}
</body>
</html>URL Routing trong Django
Tạo file
urls.pycho app:myapp/urls.py:pythonfrom django.urls import path from . import views urlpatterns = [ # path(route, view_function, name) path('', views.product_list, name='product-list'), ]Liên kết URL của app vào project:
myproject/urls.py:pythonfrom django.contrib import admin from django.urls import path, include # Thêm include urlpatterns = [ path('admin/', admin.site.urls), path('products/', include('myapp.urls')), # Bao gồm các URL từ myapp ]
Bây giờ, khi bạn truy cập http://127.0.0.1:8000/products/, nó sẽ gọi hàm product_list trong myapp/views.py.
🧑🏫 Bài 4: Django Admin và Forms
Khám phá Django Admin
Đây là một trong những tính năng mạnh mẽ nhất của Django. Nó tự động tạo ra một giao diện quản trị hoàn chỉnh cho các model của bạn.
Tạo tài khoản Superuser:
bashpython manage.py createsuperuser(Làm theo hướng dẫn để tạo username, email, password)
Đăng ký Model với Admin:
myapp/admin.py:pythonfrom django.contrib import admin from .models import Product # Đăng ký model Product để nó xuất hiện trong trang admin admin.site.register(Product)Truy cập trang Admin: Chạy server và vào
http://127.0.0.1:8000/admin/. Đăng nhập với tài khoản superuser vừa tạo. Bạn sẽ thấy một giao diện để Thêm, Sửa, Xóa các sản phẩm một cách trực quan.
Django Forms
Django Forms giúp tạo, xác thực và xử lý các form HTML một cách an toàn và hiệu quả.
Tạo Form:
myapp/forms.py(tạo file mới):pythonfrom django import forms from .models import Product class ProductForm(forms.ModelForm): class Meta: model = Product fields = ['name', 'price', 'description'] # Các trường muốn hiển thị trong formSử dụng Form trong View:
myapp/views.py:pythonfrom django.shortcuts import render, redirect from .models import Product from .forms import ProductForm def add_product(request): if request.method == 'POST': form = ProductForm(request.POST) if form.is_valid(): # Tự động kiểm tra dữ liệu form.save() # Lưu đối tượng mới vào database return redirect('product-list') # Chuyển hướng về trang danh sách else: form = ProductForm() # Tạo một form trống context = {'form': form} return render(request, 'myapp/add_product.html', context)Hiển thị Form trong Template:
myapp/templates/myapp/add_product.html:html<h1>Thêm sản phẩm mới</h1> <form method="post"> {% raw %}{% csrf_token %}{% endraw %} <!-- Bắt buộc để bảo mật --> {% raw %}{{ form.as_p }}{% endraw %} <!-- Django tự động render các thẻ input --> <button type="submit">Lưu</button> </form>Thêm URL cho view mới:
myapp/urls.py:python# ... path('add/', views.add_product, name='add-product'),
🧪 BÀI TẬP LỚN CUỐI PHẦN: Xây dựng lại Web App Quản lý Danh bạ với Django
Mô tả bài toán
Xây dựng lại ứng dụng Quản lý Danh bạ bằng Django, thay thế hoàn toàn file contacts.json bằng cơ sở dữ liệu (SQLite mặc định) và tận dụng các tính năng mạnh mẽ của Django.
Yêu cầu
Project và App Setup:
- Tạo một project Django tên là
contactbook. - Tạo một app bên trong tên là
contacts.
- Tạo một project Django tên là
Model:
- Trong
contacts/models.py, tạo một modelContactvới các trường:name(CharField)phone(CharField)email(EmailField, cho phép trống)created_at(DateTimeField, tự động thêm ngày tạo)
- Chạy
makemigrationsvàmigrateđể tạo bảng trong database.
- Trong
Django Admin:
- Tạo một tài khoản
superuser. - Đăng ký model
Contactvàocontacts/admin.py. - Truy cập trang admin và thử thêm vài liên hệ bằng tay để kiểm tra.
- Tạo một tài khoản
Views và Templates:
- Danh sách liên hệ (
/):- Tạo một view để lấy tất cả liên hệ từ database và hiển thị chúng trong một template
contact_list.html. - Template hiển thị dữ liệu trong một bảng HTML.
- Tạo một view để lấy tất cả liên hệ từ database và hiển thị chúng trong một template
- Chi tiết liên hệ (
/contact/<int:pk>/):- Tạo một view để lấy một liên hệ duy nhất dựa trên
primary key(pk) và hiển thị thông tin chi tiết trong templatecontact_detail.html.
- Tạo một view để lấy một liên hệ duy nhất dựa trên
- Thêm liên hệ (
/add/):- Tạo một
ModelFormcho modelContact. - Tạo một view để xử lý việc thêm liên hệ mới, sử dụng form vừa tạo. Template là
contact_form.html. - Sau khi thêm thành công, chuyển hướng người dùng về trang danh sách.
- Tạo một
- Danh sách liên hệ (
URLs:
- Cấu hình
urls.pycho appcontactsvà include nó vàourls.pycủa project.
- Cấu hình
(Tùy chọn nâng cao)
- Thêm chức năng Sửa (
/contact/<int:pk>/edit/) và Xóa (/contact/<int:pk>/delete/) liên hệ, cũng sử dụng Django Forms.
- Thêm chức năng Sửa (
