Học Django trong 14 ngày - Ngày 2: Mô hình và Cơ sở dữ liệu

By JoeVu, at: 08:58 Ngày 15 tháng 6 năm 2023

Thời gian đọc ước tính: __READING_TIME__ minutes

Learn Django in 14 days - Day 2: Models and Databases
Learn Django in 14 days - Day 2: Models and Databases

Mô hình trong Django được sử dụng để định nghĩa cấu trúc và hành vi của dữ liệu được lưu trữ trong cơ sở dữ liệu. Hiểu cách làm việc với các mô hình là điều cần thiết để xây dựng các ứng dụng web mạnh mẽ và có khả năng mở rộng. Vì vậy, hãy cùng tìm hiểu thế giới của các mô hình Django!

Mã nguồn mẫu được thêm vào ở đây 
 

1. Giới thiệu về cơ sở dữ liệu và mô hình Django

 

Hỗ trợ cơ sở dữ liệu của Django dựa trên lớp ánh xạ quan hệ đối tượng (ORM) mạnh mẽ của nó. ORM tách biệt các phức tạp của việc tương tác với các hệ quản trị cơ sở dữ liệu khác nhau (DBMS) và cho phép các nhà phát triển làm việc với cơ sở dữ liệu bằng mã Python thay vì viết các truy vấn SQL thô (điều này KHÔNG được khuyến nghị dưới bất kỳ hình thức nào).

 

Django hỗ trợ nhiều cơ sở dữ liệu quan hệ khác nhau, bao gồm PostgreSQL, MySQL, SQLite và Oracle, trong số những cơ sở dữ liệu khác. Tính linh hoạt này cho phép các nhà phát triển lựa chọn backend cơ sở dữ liệu phù hợp nhất với yêu cầu của dự án. Cơ sở dữ liệu Django được khuyến nghị là PostgreSQL.

 

Trong đó, một mô hình cơ sở dữ liệu là một lớp Python thể hiện một bảng cơ sở dữ liệu. Nó định nghĩa các trườngphương thức để tương tác với cơ sở dữ liệu cơ bản. Các mô hình Django cung cấp một cách làm việc với cơ sở dữ liệu ở mức cao và trực quan, giúp dễ dàng quản lý và thao tác dữ liệu hơn.

 

django model

 

Sau đó, chúng ta sẽ thảo luận một số chủ đề nâng cao với các gói bổ sung và hữu ích

 

  1. Các trường
     
  2. Mô hình
     
  3. Cấu hình cơ sở dữ liệu
     

 

2. Tạo một mô hình Django

 

Để tạo một mô hình Django, bạn cần định nghĩa một lớp Python kế thừa từ lớp cơ sở django.db.models.Model. Lớp này thể hiện một bảng trong cơ sở dữ liệu. Mỗi thuộc tính của lớp thể hiện một trường trong bảng.

 

Định nghĩa các trường

 

Các trường xác định loại dữ liệu có thể được lưu trữ trong cơ sở dữ liệu. Django cung cấp nhiều loại trường khác nhau như CharField, IntegerField, DateField, ForeignKey, và nhiều loại khác nữa. Bạn có thể chọn loại trường phù hợp dựa trên dữ liệu bạn muốn lưu trữ.

 

Các loại trường

 

Django cung cấp một loạt các loại trường để xử lý các loại dữ liệu khác nhau. Ví dụ, CharField được sử dụng để lưu trữ văn bản, IntegerField để lưu trữ số nguyên, DateField để lưu trữ ngày tháng, v.v. Việc chọn đúng loại trường đảm bảo tính toàn vẹn dữ liệu và lưu trữ hiệu quả.

 

Các tùy chọn trường

 

Các trường có thể có thêm tùy chọn để tùy chỉnh hành vi của chúng. Một số tùy chọn phổ biến bao gồm null để chỉ định xem một trường có thể trống hay không, default để cung cấp giá trị mặc định cho trường, unique để đảm bảo tính duy nhất, và nhiều tùy chọn khác nữa. Các tùy chọn này cho phép bạn tinh chỉnh hành vi của các mô hình.

 

Một ví dụ về mô hình được định nghĩa như bên dưới

 

from django.contrib.postgres.fields import ArrayField
from django.db import models


class Book(models.Model):
    author = models.ForeignKey(
        "Author",
        on_delete=models.CASCADE,
        related_name="jobs",
    )
    tags = ArrayField(
        models.CharField(max_length=256, null=True, blank=True),
        blank=True,
        null=True,
    )
    description = models.TextField()
    title = models.CharField(max_length=256, null=True, blank=True)
    category = models.CharField(max_length=256, null=True, blank=True)
    price = models.DecimalField(max_digits=None, decimal_places=None)
    
    def is_comic(self):
        return "comic" in self.category.lower()

 

3. Di chuyển cơ sở dữ liệu

 

Khi bạn thực hiện các thay đổi đối với mô hình của mình, chẳng hạn như thêm hoặc sửa đổi các trường, Django cung cấp một hệ thống di chuyển để quản lý các thay đổi này trong lược đồ cơ sở dữ liệu.

 

Tạo các di chuyển

 

Hệ thống di chuyển của Django cho phép bạn tự động tạo các câu lệnh SQL cần thiết để áp dụng các thay đổi mô hình của bạn. Bạn có thể sử dụng lệnh makemigrations để tạo các tệp di chuyển dựa trên các thay đổi được phát hiện trong mô hình của bạn.

python manage.py makemigrations app
python manage.py makemigrations

 

django model

 

 

Áp dụng các di chuyển

 

Sau khi bạn có các tệp di chuyển, bạn có thể áp dụng chúng vào cơ sở dữ liệu bằng lệnh migrate. Điều này sẽ cập nhật lược đồ cơ sở dữ liệu cho phù hợp với trạng thái hiện tại của các mô hình của bạn. Django theo dõi các di chuyển nào đã được áp dụng trong bảng django_migrations trong cơ sở dữ liệu hiện tại, giúp dễ dàng quản lý các cập nhật lược đồ.

 

python manage.py migrate

django model

 

Hoàn tác và khôi phục

 

Django cũng hỗ trợ hoàn táckhôi phục các di chuyển. Nếu bạn gặp sự cố sau khi áp dụng một di chuyển, bạn có thể hoàn tác nó để khôi phục trạng thái trước đó. Ngoài ra, bạn có thể khôi phục một tập hợp các di chuyển để quay lại một điểm thời gian cụ thể.

 

python manage.py migrate
python manage.py migrate bookstore 0001
python manage.py migrate bookstore zero  # Khôi phục lại về zero

 

Các di chuyển giả

 

 

Đây là một tính năng quan trọng khi có một số xung đột giữa các cập nhật cơ sở dữ liệu thực tế và số di chuyển được lưu trữ trong bảng django_migrations. Hãy tưởng tượng một trường hợp khi bạn đã thực hiện các thay đổi trong cơ sở dữ liệu do yêu cầu khẩn cấp từ khách hàng, nhưng bạn chưa tạo tập lệnh di chuyển và áp dụng nó vào cơ sở dữ liệu. Đây là lúc --fake migration được sử dụng.

 

python manage.py migrate bookstore 0002 --fake  # số di chuyển hiện tại là 0001, sau thay đổi này, nó sẽ là 0002 mà không cần thực hiện di chuyển thực tế.

 

Ưu điểm

 

  1. Tiến hóa lược đồ cơ sở dữ liệu: Điều này cung cấp một quá trình tiến hóa liền mạch và được kiểm soát của lược đồ cơ sở dữ liệu theo thời gian. Nó đơn giản hóa quá trình thực hiện các thay đổi đối với cấu trúc cơ sở dữ liệu mà không cần các tập lệnh SQL thủ công hoặc tạo lại toàn bộ cơ sở dữ liệu.
     

  2. Kiểm soát phiên bản: Các di chuyển được lưu trữ dưới dạng các tệp có phiên bản trong codebase của dự án, giúp dễ dàng theo dõi và quản lý các thay đổi đối với lược đồ cơ sở dữ liệu cùng với mã nguồn của ứng dụng. Điều này tạo điều kiện thuận lợi cho việc cộng tác, xem xét mã và hoàn tác nếu cần.
     

  3. Di chuyển dữ liệu: Ngoài các thay đổi về cấu trúc, các di chuyển Django còn hỗ trợ di chuyển dữ liệu. Điều này cho phép bạn viết mã Python để di chuyển và chuyển đổi dữ liệu khi thực hiện các thay đổi lược đồ, đảm bảo tính toàn vẹn dữ liệu trong quá trình di chuyển.
     

  4. Quản lý phụ thuộc: Các di chuyển hỗ trợ các phụ thuộc giữa các tệp di chuyển khác nhau. Điều này có nghĩa là bạn có thể xác định thứ tự áp dụng các di chuyển, xử lý các trường hợp phức tạp mà một di chuyển phụ thuộc vào việc hoàn thành của di chuyển khác.
     

  5. Hoàn tác và khôi phục: Điều này cho phép bạn thực hiện/hoàn tác các thay đổi đối với lược đồ cơ sở dữ liệu. Điều này có thể hữu ích trong trường hợp một di chuyển gây ra sự cố hoặc khi bạn cần khôi phục lại trạng thái trước đó.
     

Nhược điểm
 

  1. Các di chuyển phức tạp: Trong một số trường hợp cụ thể, đặc biệt là khi xử lý các thay đổi cơ sở dữ liệu phức tạp, việc viết và quản lý các di chuyển có thể trở nên khó khăn. Xử lý các trường hợp ngoại lệ, chẳng hạn như đổi tên hoặc thay đổi các trường hiện có, có thể yêu cầu sự can thiệp thủ công hoặc các tập lệnh di chuyển tùy chỉnh. Một số di chuyển tùy chỉnh có thể bị hỏng sau vài năm do nhiều cập nhật ràng buộc cơ sở dữ liệu.
     

  2. Ảnh hưởng đến hiệu suất: Các di chuyển có thể ảnh hưởng đến hiệu suất của ứng dụng trong quá trình di chuyển, đặc biệt là khi xử lý các tập dữ liệu lớn. Việc áp dụng các di chuyển phức tạp hoặc di chuyển một lượng lớn dữ liệu có thể yêu cầu xem xét kỹ lưỡng và tối ưu hóa để giảm thiểu thời gian chết và suy giảm hiệu suất. Có một mẹo để tránh điều đó bằng cách di chuyển hiệu suất trong các tác vụ nền (Celery + Redis)
     

  3. Tương tác với dữ liệu hiện có: Di chuyển dữ liệu hiện có có thể khó khăn, đặc biệt là khi xử lý các chuyển đổi dữ liệu hoặc di chuyển dữ liệu yêu cầu logic phức tạp. Việc đảm bảo tính toàn vẹn và nhất quán của dữ liệu trong quá trình di chuyển có thể yêu cầu lập kế hoạch và kiểm tra cẩn thận.
     

  4. Phụ thuộc bên ngoài: Các di chuyển có thể dựa trên các phụ thuộc hoặc yếu tố bên ngoài bên ngoài chính hệ thống di chuyển. Các thay đổi đối với các hệ thống bên ngoài, chẳng hạn như máy chủ cơ sở dữ liệu hoặc thư viện, đôi khi có thể gây ra các vấn đề về khả năng tương thích và yêu cầu thêm nỗ lực để giải quyết.

 

4. Truy vấn cơ sở dữ liệu

 

Django cung cấp một ORM mạnh mẽ (Ánh xạ quan hệ đối tượng) cho phép bạn truy vấn cơ sở dữ liệu bằng mã Python. ORM tách biệt bộ máy cơ sở dữ liệu cơ bản, giúp dễ dàng viết các truy vấn cơ sở dữ liệu theo cách không phụ thuộc vào cơ sở dữ liệu.

 

Các truy vấn cơ bản

 

Bạn có thể truy xuất các đối tượng từ cơ sở dữ liệu bằng thuộc tính objects của một lớp mô hình. Ví dụ, MyModel.objects.all() trả về tất cả các đối tượng của lớp MyModel. Bạn cũng có thể lọc các đối tượng dựa trên các tiêu chí cụ thể bằng phương thức filter().

 

Book.objects.filter(author_id__in=[1, 2, 3])  # Điều này trả về tất cả các sách có id tác giả là 1,2,3
Book.objects.filter(author__name__contains="Joe", category__icontains="comic")  # Điều này trả về tất cả các sách có tên tác giả chứa "Joe" và thể loại chứa "comic" không phân biệt chữ hoa chữ thường.

 

Lọc và sắp xếp

 

 

Django cung cấp nhiều phương pháp để lọc và sắp xếp kết quả truy vấn. Bạn có thể sử dụng các phương pháp như filter(), exclude()order_by() để thu hẹp kết quả và chỉ định thứ tự mong muốn.

 

Book.objects.filter(author__name__contains="Joe", category__icontains="comic").exclude(author__name__contains="Vu").order_by("-id")  # Điều này trả về tất cả các sách có tên tác giả chứa "Joe" và thể loại chứa "comic" không phân biệt chữ hoa chữ thường, nhưng loại trừ những cuốn sách có tên tác giả chứa "Vu" phân biệt chữ hoa chữ thường. Danh sách được trả về được sắp xếp theo "ID" giảm dần.

 

Tổng hợp và chú thích

 

 

ORM của Django cũng hỗ trợ tổng hợp và chú thích để thực hiện các phép tính và tổng hợp trên kết quả truy vấn. Bạn có thể sử dụng các phương pháp như count(), sum(), avg()annotate() để truy xuất dữ liệu tổng hợp từ cơ sở dữ liệu.

 

Book.objects.aggregate(count=Count("id"))
Book.objects.aggregate(total_price=Sum("price"))

 

5. Mối quan hệ giữa các mô hình

 

Django cho phép bạn định nghĩa các mối quan hệ giữa các mô hình, cho phép bạn thiết lập các kết nối và liên kết giữa các thực thể khác nhau trong ứng dụng của bạn.

 

Mối quan hệ một-đến-một

 

Mối quan hệ một-đến-một là một loại mối quan hệ phổ biến, trong đó mỗi bản ghi trong một mô hình được liên kết với chính xác một bản ghi trong một mô hình khác. Bạn có thể định nghĩa một mối quan hệ một-đến-một bằng cách sử dụng kiểu trường OneToOneField.

 

Mối quan hệ một-đến-nhiều

 

Mối quan hệ một-đến-nhiều thể hiện một mối quan hệ mà một bản ghi trong một mô hình có thể được liên kết với nhiều bản ghi trong một mô hình khác. Điều này được thực hiện bằng cách sử dụng kiểu trường ForeignKey.

 

Mối quan hệ nhiều-đến-nhiều

 

Mối quan hệ nhiều-đến-nhiều là một mối quan hệ phức tạp hơn, trong đó nhiều bản ghi trong một mô hình có thể được liên kết với nhiều bản ghi trong một mô hình khác. Django cung cấp kiểu trường ManyToManyField để xử lý loại mối quan hệ này.

 

6. Kế thừa mô hình

 

Django hỗ trợ kế thừa mô hình, cho phép bạn tạo các mô hình chuyên biệt hơn dựa trên các mô hình hiện có.

 

Các lớp cơ sở trừu tượng

 

Bạn có thể định nghĩa một lớp cơ sở trừu tượng làm cha cho các mô hình khác. Các lớp cơ sở trừu tượng chỉ được sử dụng cho mục đích kế thừa và không được tạo dưới dạng các bảng riêng biệt trong cơ sở dữ liệu.

 

from django.db import models


class BaseModel(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True

    @property
    def added(self):
        return self.created_at

    @property
    def updated(self):
        return self.updated_at

    @property
    def created_by(self):
        if hasattr(self, "added_by"):
            return self.added_by
        return None

 

 

Kế thừa đa bảng

 

 

Với kế thừa đa bảng, mỗi mô hình trong hệ thống phân cấp kế thừa được lưu trữ dưới dạng một bảng riêng biệt trong cơ sở dữ liệu. Django tự động tạo các mối quan hệ giữa các bảng này để duy trì cấu trúc kế thừa.

 

Mô hình proxy

 

Mô hình proxy là một dạng kế thừa mô hình khác, trong đó bạn có thể tạo một mô hình proxy hoạt động giống như mô hình gốc nhưng với một số sửa đổi. Mô hình proxy hữu ích để thêm các phương thức bổ sung hoặc thay đổi hành vi mặc định của một mô hình.

from django.contrib.postgres.fields import ArrayField
from django.db import models


class Book(models.Model):
    author = models.ForeignKey(
        "Author",
        on_delete=models.CASCADE,
        related_name="jobs",
    )
    tags = ArrayField(
        models.CharField(max_length=256, null=True, blank=True),
        blank=True,
        null=True,
    )
    description = models.TextField()
    title = models.CharField(max_length=256, null=True, blank=True)
    category = models.CharField(max_length=256, null=True, blank=True)
    price = models.DecimalField(max_digits=None, decimal_places=None)
    
    def is_comic(self):
        return "comic" in self.category.lower()


class KidBook(Book):
    class Meta:
        proxy = True

    def for_kid(self):
        return True

 

7. Các thực tiễn tốt nhất cho mô hình Django

 

  1. Quy ước đặt tên
     

    • Sử dụng danh từ số ít cho tên lớp mô hình và làm cho chúng mô tả và trực quan.
       
    • Sử dụng các chữ thường và dấu gạch dưới cho tên trường.
       
    • Cân nhắc sử dụng các tên rõ ràng và có ý nghĩa cho các trường để cải thiện khả năng đọc mã.
       
  2. Các loại trường và ràng buộc
     

    • Chọn các loại trường phù hợp thể hiện chính xác dữ liệu đang được lưu trữ.
       
    • Thêm các ràng buộc như null=True, blank=Trueunique=True để đảm bảo tính toàn vẹn dữ liệu.
       
    • Sử dụng ForeignKeyManyToManyField để thiết lập mối quan hệ giữa các mô hình.
       
  3. Chỉ mục
     

    • Xác định các trường thường được sử dụng để lọc hoặc tìm kiếm và cân nhắc thêm chỉ mục cơ sở dữ liệu để cải thiện hiệu suất truy vấn.
       
    • Sử dụng tùy chọn db_index=True của Django cho các trường thường được sử dụng trong các truy vấn.
       
  4. Phương thức và thuộc tính mô hình
     

    • Định nghĩa các phương thức trên các mô hình để đóng gói logic nghiệp vụ hoặc thực hiện các thao tác phức tạp liên quan đến dữ liệu của mô hình.
       
    • Sử dụng các thuộc tính để tính toán các giá trị dẫn xuất hoặc cung cấp quyền truy cập thuận tiện vào dữ liệu liên quan.
       
  5. Tùy chọn Meta
     

    • Sử dụng lớp Meta của Django để cung cấp các tùy chọn và siêu dữ liệu bổ sung cho các mô hình.
       
    • Chỉ định thứ tự của kết quả truy vấn bằng thuộc tính ordering.
       
    • Định nghĩa các ràng buộc duy nhất bằng unique_together để thực thi các tổ hợp trường duy nhất.
       
  6. Sử dụng di chuyển
     

    • Sử dụng hệ thống di chuyển của Django để quản lý các thay đổi đối với lược đồ cơ sở dữ liệu theo thời gian.
       
    • Tạo và áp dụng các di chuyển bất cứ khi nào có thay đổi đối với các mô hình hoặc lược đồ cơ sở dữ liệu.
       
  7. Kiểm thử
     

    • Viết các bài kiểm thử đơn vị cho các mô hình để đảm bảo hành vi và tương tác của chúng là chính xác.
       
    • Kiểm thử các phương thức, thuộc tính và mối quan hệ của mô hình để xác minh chức năng của chúng.
       
  8. Tổ chức mã
     

    • Tổ chức các mô hình thành các mô-đun hoặc tệp riêng biệt dựa trên chức năng hoặc miền liên quan.
       
    • Cân nhắc sử dụng cấu trúc ứng dụng của Django để nhóm các mô hình một cách hợp lý.
       
  9. Tài liệu
     

    • Thêm các nhận xét và chuỗi doc vào các mô hình, trường và phương thức để cung cấp tính rõ ràng và làm cho mã dễ hiểu hơn.
       
    • Tài liệu hóa bất kỳ
Tag list:
- Django
- Tips
- Django Migration
- Django best practices
- Django Examples
- Django Field Options
- Django Queryset
- Django Manager
- Django model
- Django Query
- Django Database
- Django Field
- override save
- signal

Liên quan

Theo dõi

Theo dõi bản tin của chúng tôi và không bao giờ bỏ lỡ những tin tức mới nhất.