--------------- <> -----------------
--- KHOA HỌC - CÔNG NGHỆ - GIÁO DỤC - VIỆC LÀM ---
--- Học để đi cùng bà con trên thế giới ---

Tìm kiếm trong Blog

Django (4) - Làm việc với cơ sở dữ liệu

 Bài trước: Django (3) - Mô hình MVT

-----

1         Làm việc với cơ sở dữ liệu

Cơ sở dữ liệu có nhiều loại như:

– Cơ sở dữ liệu dạng tập tin (ví dụ: text, ASCII, dbf)

– Cơ sở dữ liệu quan hệ (dạng bảng)

– Cơ sở dữ liệu hướng đối tượng

– Cơ sở dữ liệu bán cấu trúc (xml, json)

Các ngôn ngữ lập trình thường cung cấp các thư viện để làm việc với từng loại cơ sở dữ liệu.

Trong Django, model là thành phần làm việc với cơ sở dữ liệu.

1.1       Sqlite

Sqlite là hệ quản trị cơ sở dữ liệu quan hệ mã nguồn mở.

Sqlite có kích thước nhỏ, chỉ khoảng 700KB, do D. Richard Hipp tạo ra năm 2000 bằng ngôn ngữ lập trình C.

Sqlite hoạt động dưới dạng một thư viện, được nhúng trong một chương trình chứ không theo mô hình client-server. Sqlite được sử dụng để thao tác với cơ sở dữ liệu trong các ứng dụng desktop, mobile và website.

Sqlite đang được hầu hết các ngôn ngữ lập trình hỗ trợ.

Trong Sqlite, cơ sở dữ liệu được chứa trong một tập tin duy nhất.

Nhược điểm của Sqlite: không thích hợp cho các hệ thống có lượng dữ liệu lớn, phát sinh liên tục; tại một thời điểm, chỉ cho phép một người ghi dữ liệu.

Hình sau thể hiện sự khác nhau giữa Sqlite và hệ quản trị cơ sở dữ liệu client-server truyền thống:

Hình sau là kiến trúc hoạt động của Sqlite:


1.2       Thực hành với Sqlite

Mặc định, Django server sử dụng cơ sở dữ liệu Sqlite. Do vậy khi tạo một dự án web bằng Django, Sqlite sẽ được cài đặt sẵn.

Xem thông tin cấu hình trong tập tin settings.py

[settings.py]

…

DATABASES = {

    'default': {

        'ENGINE': 'django.db.backends.sqlite3',

        'NAME': BASE_DIR / 'db.sqlite3',

    }

}

…

Để minh họa việc lập trình với cơ sở dữ liệu, phần này sẽ tạo thêm web app có tên là blog.

– Vào cửa sổ dòng lệnh để tạo web app tên là blog:

D:\hocdjango\teowebsite>python manage.py startapp blog

– Khai báo app vừa tạo trong tập tin settings.py

[settings.py]

…

'django.contrib.messages',

    'django.contrib.staticfiles',

    'home', #moi them vao

    'listItems',

    'blog'

…

– Khi tạo web app, Django sẽ tạo sẵn tập tin model.py, chúng ta sẽ khai báo các model dữ liệu trong tập tin này. Khai báo model dữ liệu giống như khai báo các lớp trong lập trình hướng đối tượng. Ví dụ: tạo ra class Post để lưu các bài viết,

[blog/models.py]

from django.db import models

 

# Create your models here.

class Post(models.Model):

    title = models.CharField(max_length=100)

    body = models.TextField()

    date = models.DateTimeField(auto_now_add=True)

 

– Lớp Post kế thừa từ lớp django.db.models.Model: class Post(models.Model)

– Mỗi thuộc tính trong model kế thừa từ lớp Field, đây là lớp ảo trong Django, lớp này có nhiều lớp kế thừa khác đại diện cho các kiểu dữ liệu. Ví dụ CharField đại diện cho kiểu dữ liệu char, TextField đại diện cho kiểu dữ liệu text, DateTimeField đại diện cho kiểu dữ liệu thời gian.

– Sau khi đã tạo các class trong models.py, chạy lệnh makemigrations blog để báo cho Django cập nhật các nội dung vừa được khai báo trong models.py.

D:\hocdjango\teowebsite>python manage.py makemigrations blog

Migrations for 'blog':

  blog\migrations\0001_initial.py

    - Create model Post

– Model Post đã được tạo ra. Django sẽ tạo ra tập tin 0001_initial.py để lưu sự thay đổi về model. Mở tập tin blog\migrations\0001_initial.py để xem kết quả:

[blog\migrations\0001_initial.py]

# Generated by Django 3.1.7 on 2021-05-03 07:33

 

from django.db import migrations, models

 

class Migration(migrations.Migration):

 

    initial = True

 

    dependencies = [

    ]

 

    operations = [

        migrations.CreateModel(

            name='Post',

            fields=[

                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),

                ('title', models.CharField(max_length=100)),

                ('body', models.TextField()),

                ('date', models.DateTimeField(auto_now_add=True)),

            ],

        ),

    ]

 

– Tải và cài đặt phần mềm DB browser for SQLite để quan sát và thao tác với Sqlite: https://sqlitebrowser.org/. Vào menu File/Open Database…, tìm và mở tập tin db.sqlite3. Chưa thấy có bảng dữ liệu Post.

– Để cập nhật lại cơ sở dữ liệu, nghĩa là lưu và thực thi các thay đổi từ model vào Sqlite, sử dụng lệnh migrate.

D:\hocdjango\teowebsite>python manage.py migrate

Operations to perform:

  Apply all migrations: admin, auth, blog, contenttypes, sessions

Running migrations:

  Applying blog.0001_initial... OK

– Mở lại DB browser, sẽ thấy xuất hiện bảng blog_post.



– Vậy là đã tạo được bảng để chứa dữ liệu, từ đây có thể thực hiện các thao tác thêm, sửa, xóa các dòng tin trong bảng dữ liệu.

Xem thêm clip 7 (làm việc với model) của HowKteam:

https://www.youtube.com/watch?v=Sc2fy1XGFMc&list=PL33lvabfss1z8GYxjyMulCnhcYGk5ah8P&index=7

-----

Cập nhật: 4/5/2021

Bài sau:


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