`on_delete` trong mô hình Django có tác dụng gì?
By hientd, at: 16:12 Ngày 13 tháng 7 năm 2025
Thời gian đọc ước tính: __READING_TIME__ minutes


Trong Django, khi bạn định nghĩa một ForeignKey, đối số on_delete là bắt buộc. Nó cho Django biết phải làm gì khi đối tượng được tham chiếu bị xóa.
Cú pháp:
class Book(models.Model):
author = models.ForeignKey(Author, on_delete=models.CASCADE)
Nếu Author
bị xóa, Django sẽ tuân theo quy tắc được định nghĩa trong on_delete
để quyết định điều gì sẽ xảy ra với Book liên quan.
Các tùy chọn on_delete phổ biến
Tùy chọn | Mô tả |
---|---|
CASCADE |
Xóa cả đối tượng liên quan (ví dụ: xóa tất cả sách nếu tác giả bị xóa) |
PROTECT |
Ngăn chặn việc xóa đối tượng được tham chiếu; gây ra lỗi ProtectedError |
SET_NULL |
Đặt khóa ngoại thành NULL (yêu cầu null=True ) |
SET_DEFAULT |
Đặt thành giá trị mặc định của trường |
SET( |
Đặt thành kết quả của một hàm gọi được (ví dụ: SET(get_sentinel_user) ) |
DO_NOTHING |
Không làm gì (có thể gây ra lỗi cơ sở dữ liệu nếu không được xử lý cẩn thận) |
RESTRICT (Django 3.1+) |
Ngăn chặn việc xóa nếu bất kỳ đối tượng liên quan nào tồn tại |
Ví dụ:
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
author = models.ForeignKey(Author, on_delete=models.SET_NULL, null=True)
Trong trường hợp này, nếu tác giả bị xóa, trường tác giả của sách sẽ được đặt thành NULL
.
Câu hỏi thường gặp (FAQs)
Q1. on_delete có bắt buộc trong Django không?
A: Có. Kể từ Django 2.0, việc định nghĩa hành vi on_delete là bắt buộc khi sử dụng ForeignKey hoặc OneToOneField.
Q2. Tùy chọn on_delete an toàn nhất là gì?
A: PROTECT thường an toàn nhất — nó ngăn chặn việc xóa ngẫu nhiên các đối tượng được tham chiếu. RESTRICT (trong Django 3.1+) tương tự nhưng linh hoạt hơn với các quy tắc phức tạp.
Q3. Tôi có thể sử dụng SET_NULL mà không cần null=True
không?
A: Không. Nếu bạn sử dụng SET_NULL, bạn phải khai báo null=True cho trường đó, nếu không Django sẽ gây ra lỗi.
Q4. Sự khác biệt giữa CASCADE và SET_NULL là gì?
A:
-
CASCADE cũng xóa các đối tượng liên quan.
-
SET_NULL giữ lại các đối tượng liên quan nhưng xóa tham chiếu đến đối tượng bị xóa.
Q5. Điều gì sẽ xảy ra nếu tôi sử dụng DO_NOTHING?
A: Django sẽ không làm gì cả. Nhưng nếu cơ sở dữ liệu không hỗ trợ khóa ngoại trống, nó sẽ đưa ra lỗi IntegrityError. Bạn sẽ cần xử lý việc xóa theo cách thủ công.
Q6. Trường hợp sử dụng thực tế của SET(get_sentinel_user) là gì?
A: Thường được sử dụng trong các mô hình người dùng khi một người dùng bị xóa, gán nội dung của họ cho người dùng "nặc danh" hoặc "đã xóa" thay vì xóa nó.