Django Python 3.x - OneToOneField 使用 ContentTypes 覆盖 delete()
Django Python 3.x - OneToOneField override delete() with ContentTypes
场景:有不同的服务类型,即clothes_washing、room_cleaning和room_maintenance。
这些服务中的每一个都有共同的领域,例如 service_date。
根据场景,我有每个服务的模型和一个带有公共字段的 Service
模型。 Service
模型与各服务模型的关系为OneToOneField
.
我已经尝试在 Service
模型中重写 delete()
函数 answer 并且它适用于我,但仅适用于一项服务(如 [=18= 中的轮子) ]).但是如果我想删除服务类型?如何实现该方法?
我的models.py:
class ClothesWashing(models.Model):
# special fields for clothes_washing
service = models.OneToOneField(Service, on_delete=models.DO_NOTHING, null=True)
class RoomCleaning(models.Model):
# special fields for room_cleaning
service = models.OneToOneField(Service, on_delete=models.DO_NOTHING, null=True)
class Service(models.Model):
# common fields for all services
def delete(self, *args, **kwargs):
#here I wanna "roomcleaning" attribute to be dynamic upon content type
self.roomcleaning.delete()
return super(self.__class__, self).delete(*args, **kwargs)
您可以将on_delete
参数设置为CASCADE
:
class ClothesWashing(models.Model):
# special fields for clothes_washing
service = models.OneToOneField(Service, <b>on_delete=models.CASCADE</b>, null=True)
class RoomCleaning(models.Model):
# special fields for room_cleaning
service = models.OneToOneField(Service, <b>on_delete=models.CASCADE</b>, null=True)
on_delete=…
parameter [Django-doc] 指定当它引用的项目被删除时应该发生什么。因此,如果 Service
被删除,并且有一个 ClothesWashing
模型引用它,那么您可以指定要做什么。
通过使用 CASCADE
[Django-doc],您还将删除相关的 ClothesWashing
对象,或者按照文档中的说明:
Cascade deletes. Django emulates the behavior of the SQL constraint ON DELETE CASCADE
and also deletes the object containing the ForeignKey
.
最好用这个触发器来实现它,因为像 .delete()
这样的方法 而不是 在批量删除时总是由 ORM 调用。因此 Service.objects.all().delete()
将删除所有服务,但 永远不会 调用您的 Service
的 .delete()
方法。通过定义触发器,您可以向 Django 指定与其相关的项目应该发生什么。
在这种特定情况下,您可能希望使用 model inheritance [Django-doc]。 Django 可以自己实现一些样板逻辑(比如 OneToOneField
s 到父模型等)。
编辑:如果要删除给定的 ClothesWashing
、RoomCleaning
等服务,则可以覆盖 .delete()
方法也可以删除那个,例如,您可以创建一个抽象基础 class :
class ServiceBase(models.Model):
# special fields for clothes_washing
service = models.OneToOneField(Service, on_delete=models.CASCADE, null=True)
def delete(self, *args, **kwargs):
service = self.service
super().delete(*args, **kwargs)
self<b>.service.delete()</b>
class Meta:
<b>abstract = True</b>
class ClothesWashing(<b>ServiceBase</b>):
# …
pass
class RoomCleaning(<b>ServiceBase</b>):
# …
pass
但是,如果您使用 ORM,最终可能不会删除某些对象,因为上述方法可以避免这种情况。
场景:有不同的服务类型,即clothes_washing、room_cleaning和room_maintenance。 这些服务中的每一个都有共同的领域,例如 service_date。
根据场景,我有每个服务的模型和一个带有公共字段的 Service
模型。 Service
模型与各服务模型的关系为OneToOneField
.
我已经尝试在 Service
模型中重写 delete()
函数 answer 并且它适用于我,但仅适用于一项服务(如 [=18= 中的轮子) ]).但是如果我想删除服务类型?如何实现该方法?
我的models.py:
class ClothesWashing(models.Model):
# special fields for clothes_washing
service = models.OneToOneField(Service, on_delete=models.DO_NOTHING, null=True)
class RoomCleaning(models.Model):
# special fields for room_cleaning
service = models.OneToOneField(Service, on_delete=models.DO_NOTHING, null=True)
class Service(models.Model):
# common fields for all services
def delete(self, *args, **kwargs):
#here I wanna "roomcleaning" attribute to be dynamic upon content type
self.roomcleaning.delete()
return super(self.__class__, self).delete(*args, **kwargs)
您可以将on_delete
参数设置为CASCADE
:
class ClothesWashing(models.Model):
# special fields for clothes_washing
service = models.OneToOneField(Service, <b>on_delete=models.CASCADE</b>, null=True)
class RoomCleaning(models.Model):
# special fields for room_cleaning
service = models.OneToOneField(Service, <b>on_delete=models.CASCADE</b>, null=True)
on_delete=…
parameter [Django-doc] 指定当它引用的项目被删除时应该发生什么。因此,如果 Service
被删除,并且有一个 ClothesWashing
模型引用它,那么您可以指定要做什么。
通过使用 CASCADE
[Django-doc],您还将删除相关的 ClothesWashing
对象,或者按照文档中的说明:
Cascade deletes. Django emulates the behavior of the SQL constraint
ON DELETE CASCADE
and also deletes the object containing theForeignKey
.
最好用这个触发器来实现它,因为像 .delete()
这样的方法 而不是 在批量删除时总是由 ORM 调用。因此 Service.objects.all().delete()
将删除所有服务,但 永远不会 调用您的 Service
的 .delete()
方法。通过定义触发器,您可以向 Django 指定与其相关的项目应该发生什么。
在这种特定情况下,您可能希望使用 model inheritance [Django-doc]。 Django 可以自己实现一些样板逻辑(比如 OneToOneField
s 到父模型等)。
编辑:如果要删除给定的 ClothesWashing
、RoomCleaning
等服务,则可以覆盖 .delete()
方法也可以删除那个,例如,您可以创建一个抽象基础 class :
class ServiceBase(models.Model):
# special fields for clothes_washing
service = models.OneToOneField(Service, on_delete=models.CASCADE, null=True)
def delete(self, *args, **kwargs):
service = self.service
super().delete(*args, **kwargs)
self<b>.service.delete()</b>
class Meta:
<b>abstract = True</b>
class ClothesWashing(<b>ServiceBase</b>):
# …
pass
class RoomCleaning(<b>ServiceBase</b>):
# …
pass
但是,如果您使用 ORM,最终可能不会删除某些对象,因为上述方法可以避免这种情况。