Giới thiệu về models trong Django
Models chính là xương sống, là thành phần cốt lõi giúp lưu trữ và quản lý toàn bộ dữ liệu trong một ứng dụng Django. Bạn có thể hình dung chúng như những bản thiết kế chi tiết cho cơ sở dữ liệu của mình, quyết định cách thông tin được tổ chức, lưu trữ và truy xuất. Tuy nhiên, nhiều người mới bắt đầu thường cảm thấy bối rối và gặp khó khăn khi phải hiểu và tạo ra các models một cách chính xác. Việc khai báo sai một trường dữ liệu hay không hiểu rõ về mối quan hệ giữa chúng có thể dẫn đến những lỗi khó gỡ về sau.
Bài viết này sẽ là kim chỉ nam giúp bạn làm chủ hoàn toàn khái niệm models trong Django. Chúng tôi sẽ cùng bạn đi từ những định nghĩa cơ bản nhất, khám phá vai trò không thể thiếu của models, hướng dẫn chi tiết cách tạo và khai báo các trường dữ liệu. Không chỉ dừng lại ở lý thuyết, bạn sẽ được thực hành các thao tác quản lý dữ liệu phổ biến (CRUD là gì) và học cách quản lý models một cách hiệu quả trong các dự án thực tế. Hãy cùng AZWEB bắt đầu hành trình này!
Khái quát về models trong Django và vai trò của chúng
Để xây dựng một ứng dụng web vững chắc, việc hiểu rõ nền tảng dữ liệu là điều kiện tiên quyết. Trong Django, models chính là cầu nối giữa mã Python của bạn và cơ sở dữ liệu. Chúng ta hãy cùng tìm hiểu sâu hơn về khái niệm này và tại sao chúng lại quan trọng đến vậy.
Models là gì trong Django?
Trong Django, một model là một lớp Python (class) kế thừa từ django.db.models.Model. Mỗi model này đại diện cho một bảng trong cơ sở dữ liệu của bạn. Thay vì phải viết các câu lệnh SQL phức tạp để tạo bảng, bạn chỉ cần định nghĩa một lớp Python đơn giản. Mỗi thuộc tính (attribute) trong lớp model sẽ tương ứng với một cột trong bảng dữ liệu đó.
Điều kỳ diệu nằm ở hệ thống ORM là gì (Object-Relational Mapping) của Django. ORM hoạt động như một “thông dịch viên” tài ba, tự động chuyển đổi các lớp model Python của bạn thành các câu lệnh SQL mà cơ sở dữ liệu có thể hiểu được. Nhờ đó, bạn có thể tương tác với cơ sở dữ liệu bằng ngôn ngữ Python quen thuộc, giúp mã nguồn trở nên sạch sẽ, dễ đọc và độc lập với hệ quản trị cơ sở dữ liệu cụ thể (PostgreSQL là gì, MySQL là gì, SQLite,…).
Vai trò quan trọng của models trong phát triển Django
Models không chỉ đơn thuần là định nghĩa cấu trúc dữ liệu, chúng còn đóng vai trò trung tâm trong toàn bộ vòng đời phát triển ứng dụng Django với nhiều lợi ích vượt trội.
- Giúp quản lý dữ liệu linh hoạt theo hướng đối tượng: Thay vì nghĩ về các bảng và hàng, bạn có thể tư duy theo các đối tượng trong thế giới thực. Ví dụ, một đối tượng
BaiVietcó các thuộc tính nhưtieu_de,noi_dung,ngay_dang. Cách tiếp cận này trực quan và dễ quản lý hơn rất nhiều. - Tự động tạo và quản lý cấu trúc cơ sở dữ liệu: Với hệ thống “migrations“, Django có thể tự động tạo và cập nhật schema của cơ sở dữ liệu dựa trên những thay đổi trong file
models.pycủa bạn. Bạn không cần phải viết thủ công các lệnhCREATE TABLEhayALTER TABLEnữa. - Hỗ trợ thao tác CRUD dễ dàng: Models cung cấp một API mạnh mẽ và tiện lợi để thực hiện các thao tác cơ bản: Tạo (Create), Đọc (Read), Cập nhật (Update), và Xóa (Delete) dữ liệu. Tất cả đều được thực hiện thông qua các phương thức Python đơn giản.

Cách tạo models trong Django bằng Python
Bây giờ chúng ta sẽ đi vào phần thực hành: tạo ra những model đầu tiên của bạn. Quá trình này rất đơn giản và tuân theo quy ước của Django. Bạn chỉ cần làm việc với các file Python và Django sẽ lo phần còn lại.
Tạo file models.py và khai báo class model
Khi bạn tạo một ứng dụng (app) mới trong Django bằng lệnh python manage.py startapp ten_app, Django sẽ tự động tạo ra một cấu trúc thư mục, trong đó có file ten_app/models.py. Đây chính là nơi bạn sẽ định nghĩa tất cả các model cho ứng dụng đó.
Để tạo một model, bạn chỉ cần khai báo một lớp Python mới và cho nó kế thừa từ lớp django.db.models.Model. Tên của lớp sẽ được Django tự động chuyển thành tên bảng trong cơ sở dữ liệu. Ví dụ, một model tên là SanPham sẽ tương ứng với một bảng tên là ten_app_sanpham.
Dưới đây là một ví dụ về cách khai báo một model SanPham đơn giản trong file products/models.py:
from django.db import models
class SanPham(models.Model):
# Các trường dữ liệu sẽ được định nghĩa ở đây
pass

Định nghĩa các trường dữ liệu (Fields) trong models
Sau khi đã có lớp model, bước tiếp theo là định nghĩa các trường dữ liệu (fields), tương ứng với các cột trong bảng. Django cung cấp rất nhiều loại trường khác nhau để phù hợp với mọi kiểu dữ liệu bạn cần lưu trữ.
Mỗi trường được khai báo như một thuộc tính của lớp, và là một thể hiện của một lớp Field cụ thể (ví dụ: models.CharField). Dưới đây là một số trường phổ biến nhất:
- CharField: Dùng để lưu trữ các chuỗi văn bản ngắn, như tiêu đề, tên, slug. Bắt buộc phải có tham số
max_length. - TextField: Dùng cho các đoạn văn bản dài không giới hạn, như nội dung bài viết, mô tả sản phẩm.
- IntegerField: Dùng để lưu trữ số nguyên.
- FloatField: Dùng để lưu trữ số thực (dấu phẩy động).
- BooleanField: Dùng để lưu giá trị True/False.
- DateTimeField: Dùng để lưu thông tin ngày và giờ. Có thể tự động gán giá trị hiện tại với
auto_now_add=True(khi tạo) hoặcauto_now=True(khi cập nhật). - ForeignKey: Dùng để tạo mối quan hệ nhiều-một với một model khác (ví dụ: một sản phẩm thuộc về một danh mục).
Ngoài ra, mỗi trường còn có các tham số tùy chọn để điều chỉnh hành vi của nó:
- max_length: (Bắt buộc cho CharField) Độ dài tối đa của chuỗi.
- default: Giá trị mặc định cho trường nếu không có giá trị nào được cung cấp.
- null=True: Cho phép trường có giá trị NULL trong cơ sở dữ liệu.
- blank=True: Cho phép trường để trống trong các form (ví dụ: Django Admin).
Hãy xem ví dụ chi tiết hơn về model SanPham:
from django.db import models
class SanPham(models.Model):
ten_san_pham = models.CharField(max_length=200)
mo_ta = models.TextField(blank=True)
gia = models.IntegerField(default=0)
ngay_tao = models.DateTimeField(auto_now_add=True)
con_hang = models.BooleanField(default=True)
def __str__(self):
return self.ten_san_pham
Trong ví dụ trên, chúng ta đã định nghĩa các trường cho tên, mô tả, giá, ngày tạo và tình trạng còn hàng của sản phẩm. Phương thức __str__ được định nghĩa để trả về một chuỗi đại diện cho đối tượng, giúp hiển thị tên sản phẩm trong giao diện quản trị của Django một cách thân thiện hơn.
Thực hiện các thao tác CRUD thông qua models
Khi bạn đã định nghĩa xong các model của mình, Django ORM cung cấp một giao diện lập trình ứng dụng (API) cực kỳ mạnh mẽ và trực quan để bạn tương tác với dữ liệu. Các thao tác này thường được gọi là CRUD: Create (Tạo), Read (Đọc), Update (Cập nhật), và Delete (Xóa).
Tạo và lưu dữ liệu mới (Create)
Để tạo một bản ghi mới trong cơ sở dữ liệu, bạn chỉ cần khởi tạo một đối tượng từ lớp model của mình và gọi phương thức .save(). Django sẽ tự động chuyển đổi đối tượng này thành một câu lệnh INSERT trong SQL.
Giả sử chúng ta có model SanPham đã định nghĩa ở trên. Để thêm một sản phẩm mới, bạn có thể làm như sau:
# Đầu tiên, import model của bạn
from products.models import SanPham
# Cách 1: Tạo đối tượng rồi gọi save()
sp_moi = SanPham(ten_san_pham="Laptop AZWEB Pro", gia=25000000)
sp_moi.save()
# Cách 2: Sử dụng phương thức .objects.create() tiện lợi hơn
sp_khac = SanPham.objects.create(ten_san_pham="Chuột không dây", gia=500000)

Cả hai cách trên đều có kết quả như nhau: một hàng mới sẽ được thêm vào bảng products_sanpham trong cơ sở dữ liệu của bạn. Phương thức create() sẽ khởi tạo và lưu đối tượng chỉ trong một bước, rất tiện lợi.
Đọc, cập nhật và xóa dữ liệu (Read, Update, Delete)
Việc truy xuất và quản lý dữ liệu hiện có cũng vô cùng đơn giản với Django ORM. Mọi truy vấn đều bắt đầu từ Model.objects.
Đọc (Read):
Django cung cấp nhiều phương thức để lấy dữ liệu. Phổ biến nhất là all(), filter(), và get().
- Lấy tất cả đối tượng:
tat_ca_san_pham = SanPham.objects.all()– trả về một QuerySet chứa tất cả sản phẩm. - Lọc đối tượng theo điều kiện:
san_pham_gia_re = SanPham.objects.filter(gia__lt=1000000)– trả về một QuerySet chứa các sản phẩm có giá dưới 1 triệu.__ltlà một “lookup” có nghĩa là “less than”. - Lấy một đối tượng duy nhất:
sp = SanPham.objects.get(id=1)– trả về một đối tượng duy nhất cóidlà 1. Lưu ý: nếu không tìm thấy hoặc tìm thấy nhiều hơn một kết quả,get()sẽ gây ra lỗi.

Cập nhật (Update):
Để cập nhật một bản ghi, bạn chỉ cần lấy đối tượng đó ra, thay đổi các thuộc tính của nó, và gọi lại phương thức .save().
sp_can_sua = SanPham.objects.get(id=1)
sp_can_sua.gia = 24500000 # Giảm giá sản phẩm
sp_can_sua.save()
Xóa (Delete):
Để xóa một bản ghi, bạn lấy đối tượng ra và gọi phương thức .delete().
sp_can_xoa = SanPham.objects.get(id=2)
sp_can_xoa.delete()
Thao tác này sẽ xóa vĩnh viễn hàng tương ứng khỏi cơ sở dữ liệu. Thật đơn giản phải không? Bạn đã có thể quản lý toàn bộ dữ liệu chỉ bằng vài dòng lệnh Python.
Quản lý và sử dụng models hiệu quả trong dự án Django
Tạo models chỉ là bước khởi đầu. Để duy trì một dự án Django khỏe mạnh và dễ dàng mở rộng, việc quản lý models một cách khoa học là vô cùng quan trọng. Dưới đây là các kỹ thuật và công cụ thiết yếu bạn cần nắm vững.
Sử dụng migration để đồng bộ database
Khi bạn thay đổi model của mình – ví dụ như thêm một trường mới, xóa một trường, hoặc thay đổi thuộc tính của trường – cấu trúc cơ sở dữ liệu cần phải được cập nhật tương ứng. Django giải quyết vấn đề này một cách thanh lịch thông qua hệ thống “migrations“.
Migration giống như một hệ thống kiểm soát phiên bản (version control) cho schema cơ sở dữ liệu của bạn. Quy trình làm việc rất đơn giản:
- Tạo file migration: Sau khi thay đổi file
models.py, bạn chạy lệnh:python manage.py makemigrations. Django sẽ phân tích các thay đổi và tạo ra một file migration trong thư mụcmigrations/của app. File này chứa mã Python mô tả các thay đổi cần thực hiện. - Áp dụng migration: Để thực sự áp dụng những thay đổi này vào cơ sở dữ liệu, bạn chạy lệnh:
python manage.py migrate. Django sẽ đọc các file migration chưa được áp dụng và thực thi các lệnh SQL cần thiết.
Việc tuân thủ quy trình này giúp đảm bảo rằng cấu trúc cơ sở dữ liệu của bạn luôn đồng bộ với mã nguồn, đặc biệt là khi làm việc nhóm.

Tổ chức models khi dự án lớn
Khi dự án của bạn phát triển, việc nhồi nhét hàng chục model vào một file models.py duy nhất sẽ trở nên rất khó quản lý. Django rất linh hoạt và cho phép bạn tổ chức lại cấu trúc này.
- Phân chia models theo app hoặc module: Cách tiếp cận phổ biến nhất là chia nhỏ dự án thành các ứng dụng (app) logic. Ví dụ: app
productsquản lý các model liên quan đến sản phẩm, appusersquản lý người dùng, appordersquản lý đơn hàng. Mỗi app sẽ có filemodels.pyriêng. - Xây dựng relationships và model inheritance: Tận dụng các trường quan hệ như
ForeignKey,ManyToManyField, vàOneToOneFieldđể tạo liên kết logic giữa các model. Ngoài ra, tính năng kế thừa model (model inheritance) cho phép bạn tạo các model chung (abstract models) để tái sử dụng các trường dữ liệu phổ biến, tránh lặp lại mã.
Sử dụng Django Admin để quản lý dữ liệu từ models
Một trong những tính năng mạnh mẽ nhất của Django là giao diện quản trị (Admin) được tạo tự động. Chỉ với vài dòng mã, bạn có thể có ngay một giao diện CRUD hoàn chỉnh để quản lý dữ liệu từ các model của mình.
Để hiển thị một model trong trang Admin, bạn chỉ cần đăng ký nó trong file admin.py của ứng dụng tương ứng:
from django.contrib import admin
from .models import SanPham
# Đăng ký model SanPham với trang Admin
admin.site.register(SanPham)
Sau khi đăng ký, bạn có thể truy cập trang quản trị của Django, đăng nhập, và bạn sẽ thấy model SanPham xuất hiện. Tại đây, bạn có thể dễ dàng thêm, sửa, xóa các sản phẩm mà không cần viết thêm bất kỳ dòng mã giao diện nào. Đây là một công cụ tuyệt vời để quản lý dữ liệu nội bộ và gỡ lỗi nhanh chóng.
Các vấn đề thường gặp khi tạo và sử dụng models
Trong quá trình làm việc với Django models, bạn chắc chắn sẽ gặp phải một số lỗi phổ biến. Hiểu rõ nguyên nhân và cách khắc phục sẽ giúp bạn tiết kiệm rất nhiều thời gian và công sức. Dưới đây là hai trong số những vấn đề thường gặp nhất.
Lỗi khi migration do sai khai báo trường dữ liệu
Đây là lỗi kinh điển mà hầu hết các lập trình viên Django đều từng trải qua. Bạn thêm một trường mới vào model hiện có, chạy makemigrations, và sau đó migrate báo lỗi. Nguyên nhân phổ biến nhất là bạn đang thêm một trường không cho phép giá trị NULL (null=False) vào một bảng đã có dữ liệu, nhưng lại không cung cấp giá trị mặc định (default).
Khi đó, Django không biết phải điền giá trị gì cho các hàng dữ liệu đã tồn tại. Để giải quyết, bạn có hai lựa chọn:
- Cung cấp giá trị mặc định một lần: Khi chạy
makemigrations, Django sẽ hỏi bạn. Bạn có thể chọn phương án 1 và nhập một giá trị mặc định để Django sử dụng cho các hàng hiện có. - Sửa đổi model và tạo lại migration: Cách tốt hơn là quay lại file
models.py, thêmdefault=gia_tri_mac_dinhhoặcnull=Truevào trường mới. Sau đó, xóa file migration vừa tạo lỗi và chạy lạimakemigrations. Cách này đảm bảo model của bạn luôn rõ ràng và nhất quán.
Hãy luôn kiểm tra kỹ các thay đổi trong model trước khi tạo migration để tránh những lỗi không đáng có.
Vấn đề dữ liệu trùng lắp hoặc không hợp lệ
Chất lượng dữ liệu là yếu tố sống còn của một ứng dụng. Nếu không có các biện pháp ràng buộc, người dùng có thể nhập vào những dữ liệu không mong muốn, gây ra sự thiếu nhất quán và lỗi logic.
Django models cung cấp nhiều cách để đảm bảo tính toàn vẹn của dữ liệu:
- Sử dụng ràng buộc ở cấp độ cơ sở dữ liệu: Bạn có thể thêm
unique=Truevào một trường để đảm bảo không có hai bản ghi nào có cùng giá trị ở trường đó (ví dụ:emailcủa người dùng,slugcủa bài viết). - Sử dụng validators: Django cho phép bạn định nghĩa các hàm hoặc lớp
validatorđể kiểm tra dữ liệu trước khi lưu. Ví dụ, bạn có thể viết một validator để đảm bảo một trường số nguyên luôn là số dương. - Ghi đè phương thức
clean(): Để thực hiện các logic kiểm tra phức tạp hơn liên quan đến nhiều trường, bạn có thể ghi đè phương thứcclean()của model. Phương thức này sẽ được gọi trước khi lưu dữ liệu, cho phép bạn thực hiện các kiểm tra tùy chỉnh và ném raValidationErrornếu dữ liệu không hợp lệ.
Bằng cách áp dụng các kỹ thuật này, bạn có thể chủ động ngăn chặn dữ liệu xấu ngay từ tầng model, giúp ứng dụng của bạn trở nên mạnh mẽ và đáng tin cậy hơn.
Best Practices khi làm việc với models trong Django
Viết mã chỉ để nó hoạt động là chưa đủ. Để xây dựng các ứng dụng Django chuyên nghiệp, dễ bảo trì và mở rộng, việc tuân thủ các quy tắc và thực hành tốt nhất (best practices) khi làm việc với models là vô cùng cần thiết. Dưới đây là những lời khuyên từ AZWEB giúp bạn nâng cao chất lượng mã nguồn của mình.

- Luôn định nghĩa
verbose_namevàhelp_textcho trường dữ liệu: Điều này giúp mã nguồn của bạn tự diễn giải.verbose_namesẽ được dùng làm nhãn hiển thị trong Django Admin, cònhelp_textcung cấp một đoạn mô tả ngắn gọn, giúp người quản trị hiểu rõ ý nghĩa của từng trường. - Sử dụng model methods để định nghĩa logic liên quan đến dữ liệu: Nếu bạn có một logic nghiệp vụ liên quan trực tiếp đến một đối tượng (ví dụ: tính tuổi của người dùng từ ngày sinh, kiểm tra một sản phẩm có đang khuyến mãi hay không), hãy viết nó thành một phương thức ngay trong lớp model. Điều này giúp đóng gói logic và dễ dàng tái sử dụng.
- Tránh đặt logic xử lý dữ liệu trong views, hãy tận dụng model managers: Views chỉ nên chịu trách nhiệm xử lý request và response. Các logic truy vấn dữ liệu phức tạp (ví dụ: lấy danh sách các bài viết được xuất bản, lọc sản phẩm theo nhiều tiêu chí) nên được đặt trong các phương thức của Model Manager tùy chỉnh. Điều này tuân thủ nguyên tắc “Fat Models, Thin Views”.
- Không hardcode giá trị, sử dụng choices hoặc constants: Khi một trường có một tập hợp các giá trị cố định (ví dụ: trạng thái đơn hàng: ‘chờ xử lý’, ‘đang giao’, ‘hoàn thành’), hãy định nghĩa chúng bằng tùy chọn
choices. Điều này giúp tránh lỗi chính tả và làm cho mã nguồn dễ đọc hơn. - Thường xuyên tạo và áp dụng migration đúng lúc: Hãy tạo migration sau mỗi thay đổi nhỏ và có ý nghĩa trên model, thay vì dồn nhiều thay đổi vào một migration lớn. Đặt tên file migration một cách tường minh nếu cần. Điều này giúp việc theo dõi và gỡ lỗi khi có sự cố trở nên dễ dàng hơn rất nhiều.
- Sử dụng
__str__một cách thông minh: Luôn định nghĩa phương thức__str__(self)cho mọi model. Nó không chỉ giúp hiển thị đối tượng một cách thân thiện trong Django Admin mà còn rất hữu ích khi bạn gỡ lỗi trong shell.
Kết luận
Qua bài viết này, chúng ta đã cùng nhau khám phá một trong những khái niệm nền tảng và mạnh mẽ nhất của Django: Models. Chúng không chỉ là bản thiết kế cho cơ sở dữ liệu mà còn là trái tim của việc quản lý dữ liệu, cung cấp một giao diện lập trình hướng đối tượng thanh lịch và hiệu quả. Việc nắm vững cách tạo, quản lý và tương tác với models chính là chìa khóa để xây dựng các ứng dụng web phức tạp và đáng tin cậy.
Từ việc định nghĩa các lớp và trường dữ liệu, thực hiện các thao tác CRUD, cho đến việc quản lý bằng migrations và tối ưu hóa thông qua các best practices, bạn đã có một nền tảng vững chắc để làm việc với dữ liệu trong bất kỳ dự án Django nào. Hãy nhớ rằng, một cấu trúc model được thiết kế tốt sẽ giúp dự án của bạn ổn định, dễ bảo trì và dễ dàng mở rộng trong tương lai.
Hành trình của bạn với Django models chưa dừng lại ở đây. Bước tiếp theo, chúng tôi khuyến khích bạn tìm hiểu sâu hơn về các mối quan hệ phức tạp giữa các model như ForeignKey, ManyToManyField, OneToOneField, và khám phá các chủ đề nâng cao như signals để tự động hóa các tác vụ khi dữ liệu thay đổi. Chúc bạn thành công trên con đường trở thành một lập trình viên Django chuyên nghiệp!