Bài trước: Django(2) - Tạo ứng dụng đầu tiên
-----
1
Mô hình MVT
Đọc thêm: https://data-flair.training/blogs/django-mtv-architecture/
Mô hình MVT là biến thể của mô hình MVC. MVT là viết tắt của
Model-View-Template. Về bản chất MVT và MVC đều giống nhau, đều chia ứng dụng
ra thành ba thành phần: phần xử lý logic, phần hiển thị và phần thao tác với cơ
sở dữ liệu.
Sự khác biệt của mô hình MVT và MVC được minh họa trong bảng
sau:
Mô hình MVC |
Mô hình MVT |
Chức năng |
Model |
Model |
Làm việc với cơ
sở dữ liệu |
View |
Template |
Hiển thị giao
diện |
Controller |
View |
Xử lý logic |
1.1
Template
Template nghĩa là bản mẫu, là công cụ để tạo ra các giao
diện web. Trong một bản mẫu sẽ có những phần cố định (static) và những phần
được bổ sung sau (dynamic).
Django có hai công cụ để tạo các template là DTL và Jinja2.
Để tạo ra các template, bạn sẽ sử dụng cú pháp của một trong
hai công cụ là DTL hoặc Jinja2, sau đó chuyển template cho template engine để
chuyển sang mã HTML.
Như đã biết Template trong Django có vai trò như View trong
mô hình MVC, phụ trách việc hiển thị nội dung.
Phân tích một tình huống cụ thể để hiểu về hoạt động của
template. Hình sau là một bố cục phổ biến của trang web:
Ở bố cục trên, các vùng Top Navigation, Header, Footer
thường là không đổi giữa các trang trong một website; vùng Side Navigation và
Page Content chính là nội dung riêng biệt của mỗi trang. Vậy,
– Vùng tĩnh gồm: Top Navigation, Header, Footer (viết trong
tập tin base.html)
– Vùng động gồm: Side Navigation và Page Content (viết trong
các trang riêng biệt, ví dụ trang home.html)
Cú pháp của Jinja2 gồm bốn thành phần:
– Variables (biến)
– Tags (thẻ)
– Filters (bộ lọc)
– Comments (chú thích)
Biến
Biến được sử dụng để chèn dữ liệu động trong một template.
Cú pháp sử dụng biến {{ tên_biến}}. Biến làm việc theo kiểu key:value, nghĩa là
khi thực thi template, giá trị của biến (value) sẽ thay thế cho tên_biến (key).
Ví dụ:
Họ của tôi là {ho} và tên của tôi là {ten}.
Với ho : Nguyễn, ten : Tèo. Kết quả chạy template sẽ có kết quả là
Họ của tôi là Nguyễn và tên của tôi là Tèo.
Thẻ
Thẻ được sử dụng
để thể hiện một số xử lý logic trong quá trình kết xuất từ template ra trang
kết quả (HTML).
Ví dụ: một thẻ có
thể xuất ra nội dung (content), cấu trúc điều khiển.
Bạn có thể sử
dụng thẻ để thực hiện lệnh if, for, lấy dữ liệu từ cơ sở dữ liệu.
Thẻ được bao bằng
cặp dấu {% %}.
Ví dụ:
<title>{% block title %}{% endblock %}</title>
Thẻ block nói cho
template engine biết là các template con có thể ghi đè nội dung vào vùng này.
Cụ thể title của trang con có thể ghi đè vào title của trang cha (base).
1.2 Áp dụng template vào dự án
Trong web app, tạo thư mục templates, trong thư mục
templates tạo thư mục pages để chứa các template, trong pages tạo tập tin
base.html.
[base.html]
<!doctype html>
<html>
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
Nội dung
{% block content %}
{% endblock %}
</body>
</html>
Tạo trang home.html dựa trên trang base.html.
[home.html]
{% extends "pages/base.html" %}
{% block title %}Home{% endblock %}
{% block content %}
<p>Chào bác tèo.</p>
<p>Đây là trang app home.</p>
{% endblock %}
Trang base.html
chính là cái khung cơ bản của trang web, chứa các vùng không thay đổi giữa các
trang.
Trang home.html là nội dung riêng biệt của trang home.
Template được thiết kế theo nguyên tắc không lặp lại (DRY:
Don’t Repeat Yourself), nó sẽ viết những phần chung vào trang base.html, sau đó
ghép các trang riêng biệt với trang base.html để tạo ra trang kết quả. Hay nói
cách khác, các trang riêng biệt sẽ kế thừa từ trang base.html. Xem hình minh
họa:
Đọc thêm về base template tại đây: https://jinja.palletsprojects.com/en/2.11.x/templates/
Xem thêm clip 4 (template và jinja) của HowKteam: https://www.youtube.com/watch?v=p1q39gPvDAI&list=PL33lvabfss1z8GYxjyMulCnhcYGk5ah8P&index=4
1.3 Bootstrap trong Django
Trong thư mục home (web app), tạo thư mục tên là static để
chứa bootstrap.
Tải bootstrap từ trên mạng (ví dụ chọn phiên bản 4), giải
nén và chép hai thư mục css và js vào static.
Tạo giao diện mẫu cho một blog trong tập tin base.html.
Trong base.html, sử dụng thẻ {% load static %} để lấy đường
dẫn của thư mục static lưu vào nhãn static.
Ví dụ:
{% load static %}
Sử dụng,
<link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}" type="text/css">
Đọc thêm về staticfiles: https://django.readthedocs.io/en/stable/howto/static-files/index.html
[base.html]
<!doctype html>
<html>
<head>
{% load static %}
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}" type="text/css">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-sm-2">
<img src="{% static 'images/goldfish.png' %}" class="responsive-img" style="max-height:50px">
</div>
<div class="col-sm-10">
<h1>My blog</h1>
</div>
</div>
</div>
{% block content %}
{% endblock %}
</body>
</html>
Đọc thêm về Bootstrap để tạo ra các trang theo yêu cầu.
1.4 Liên kết trang trong Template
Như đã biết, các định tuyến URL trong project/urls.py thực
hiện ở mức web app, ví dụ path('home/',
include('home.urls')) sau đó, các định tuyến URL chi tiết hơn sẽ được tạo
trong web app/urls.py. Ví dụ: path('',
views.index)
[home/urls.py]
from django.urls import path
from . import views
urlpatterns = [
path('', views.index)
]
Ở đoạn mã trên, định tuyến trong web app/urls.py đã dẫn tới
tập tin views, với hàm mặc định được gọi là index().
[views.py]
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return render(request, "pages/home.html")
Trong tập tin views.py, cho thấy nếu hàm index() được gọi
thì sẽ hiển thị trang “pages/home.html”.
Nếu muốn thêm một định tuyến mới, thì cần chỉnh sửa ở hai
tập tin là app/urls.py và views.py.
Ví dụ để thêm trang contact.html, cần thêm đoạn mã sau:
[home/urls.py]
from django.urls import path
from . import views
urlpatterns = [
path('', views.index),
path('contact/', views.contact)
]
[views.py]
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return render(request, "pages/home.html")
def contact(request):
return render(request, "pages/contact.html")
Có thể điều chỉnh để khi người dùng nhập tên miền trang web
thì vào thẳng trang home.html ở tập tin project/urls.py.
Ví dụ,
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('home.urls')),
path('listItems/', include('listItems.urls'))
]
Xem thêm clip 5 và 6 (sử dụng bootstrap) của HowKteam:
https://www.youtube.com/watch?v=_D5WGp2chtk&list=PL33lvabfss1z8GYxjyMulCnhcYGk5ah8P&index=5
https://www.youtube.com/watch?v=TzWwzM0SBRk&list=PL33lvabfss1z8GYxjyMulCnhcYGk5ah8P&index=6
-----
Cập nhật: 28/4/2021
Bài sau: Django (4) - Làm việc với cơ sở dữ liệu
-----
Bạn muốn tự học HTML bài bản? Xem thêm