Điều này sẽ thúc giải pháp từ việc thực hiện trong ứng dụng của tôi.Một số mã là hình thức LWN's answer.
Có 4 tình huống mà dữ liệu sẽ bị xóa:
- truy vấn SQL
- Calling
delete()
trên dụ mẫu: project.delete()
- Calling
delete()
trên QuerySet innstance: Project.objects.all().delete()
- Đã xóa trường ForeignKey trên một Mô hình khác
Trong khi không có gì nhiều bạn có thể làm với trường hợp đầu tiên, ba khác có thể được kiểm soát hạt mịn. Một lời khuyên là, trong hầu hết trường hợp, bạn không bao giờ nên xóa chính dữ liệu, bởi vì những dữ liệu đó phản ánh lịch sử và cách sử dụng ứng dụng của chúng tôi. Thay vào đó, cài đặt trên active
Trường Boolean được ưu tiên.
Để ngăn chặn delete()
trên dụ Model, lớp con delete()
trong việc kê khai mẫu của bạn:
def delete(self):
self.active = False
self.save(update_fields=('active',))
Trong khi delete()
trên QuerySet dụ cần một chút thiết lập với một người quản lý đối tượng tùy chỉnh như trong LWN's answer.
Gói này lên đến triển khai có thể tái sử dụng:
class ActiveQuerySet(models.QuerySet):
def delete(self):
self.save(update_fields=('active',))
class ActiveManager(models.Manager):
def active(self):
return self.model.objects.filter(active=True)
def get_queryset(self):
return ActiveQuerySet(self.model, using=self._db)
class ActiveModel(models.Model):
""" Use `active` state of model instead of delete it
"""
active = models.BooleanField(default=True, editable=False)
class Meta:
abstract = True
def delete(self):
self.active = False
self.save()
objects = ActiveManager()
Cách sử dụng, chỉ cần su bclass ActiveModel
lớp:
class Project(ActiveModel):
...
Tuy nhiên đối tượng của chúng tôi vẫn có thể bị xóa nếu có một trong các lĩnh vực ForeignKey nó được xóa:
class Employee(models.Model):
name = models.CharField(name, unique=True)
class Project(models.Model):
name = models.CharField(name, unique=True)
manager = purchaser = models.ForeignKey(
Employee, related_name='project_as_manager')
>>> manager.delete() # this would cause `project` deleted as well
Điều này có thể được ngăn chặn bằng cách thêm on_delete argument của trường mẫu:
class Project(models.Model):
name = models.CharField(name, unique=True)
manager = purchaser = models.ForeignKey(
Employee, related_name='project_as_manager',
on_delete=models.PROTECT)
Mặc định của on_delete
là CASCADE
sẽ làm cho trường hợp của bạn bị xóa, bằng cách sử dụng PROTECT
thay vào đó sẽ tăng ProtectedError
(một phân lớp của IntegrityError
). Một mục đích khác của điều này là ForeignKey của dữ liệu nên được giữ như một tài liệu tham khảo.
Điều này không khả thi chỉ sử dụng mã Python; bản thân cơ sở dữ liệu cũng cần được sửa đổi. –
Cảm ơn nhận xét của bạn. Tôi đang tìm phần Python/Django đầu tiên và xem cách xa mà được tôi trong ứng dụng của tôi. – dyve