Django(3) - Mô hình MVT

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