我有一个 IPv4Manage 模型,其中有一个vlanedipv4network字段:
class IPv4Manage(models.Model):
...
vlanedipv4network = models.ForeignKey(
to=VlanedIPv4Network, related_name="ipv4s", on_delete=models.xxx, null=True)
Run Code Online (Sandbox Code Playgroud)
众所周知,在on_deleteparam 上,我们一般会填充models.xxx,例如models.CASCADE。
是否可以自定义一个函数,在那里填充?我想在那里做其他逻辑事情。
的选择on_delete可以在django/db/models/deletion.py
例如,models.SET_NULL 实现为:
def SET_NULL(collector, field, sub_objs, using):
collector.add_field_update(field, None, sub_objs)
Run Code Online (Sandbox Code Playgroud)
而models.CASCADE(稍微复杂一点)被实现为:
def CASCADE(collector, field, sub_objs, using):
collector.collect(sub_objs, source=field.remote_field.model,
source_attr=field.name, nullable=field.null)
if field.null and not connections[using].features.can_defer_constraint_checks:
collector.add_field_update(field, None, sub_objs)
Run Code Online (Sandbox Code Playgroud)
因此,如果您弄清楚这些参数是什么,那么您应该能够定义自己的函数以传递给on_delete模型字段的参数。 collector很可能是Collector(在同一文件中定义的,不确定它的确切用途)的实例,field很可能是模型字段被删除,sub_objs很可能是该字段与对象相关的实例,并using表示正在使用的数据库。
也有用于删除的自定义逻辑的替代方案,以防覆盖 on_delete 对您来说可能有点矫枉过正。
该post_delete和pre_delete允许你之前或实例被删除后,定义一些自定义的逻辑来运行。
from django.db.models.signals import post_save
def delete_ipv4manage(sender, instance, using):
print('{instance} was deleted'.format(instance=str(instance)))
post_delete.connect(delete_ipv4manage, sender=IPv4Manage)
Run Code Online (Sandbox Code Playgroud)
最后,您可以覆盖delete()Model/Queryset的方法,但是请注意使用此方法进行批量删除的注意事项:
批量操作不会调用覆盖的模型方法
请注意,当使用 QuerySet 批量删除对象或作为级联删除的结果时,不一定会调用对象的 delete() 方法。为确保执行自定义删除逻辑,您可以使用 pre_delete 和/或 post_delete 信号。
另一个有用的解决方案是使用models.SET()你可以传递函数的地方(下面例子中的deleted_guest)
来宾 = models.ForeignKey('来宾', on_delete=models.SET(deleted_guest))
和功能deleted_guest是
DELETED_GUEST_EMAIL = 'deleted-guest@introtravel.com'
def deleted_guest():
""" used for setting the guest field of a booking when guest is deleted """
from intro.models import Guest
from django.conf import settings
deleted_guest, created = Guest.objects.get_or_create(
first_name='Deleted',
last_name='Guest',
country=settings.COUNTRIES_FIRST[0],
email=DELETED_GUEST_EMAIL,
gender='M')
return deleted_guest
Run Code Online (Sandbox Code Playgroud)
你不能发送任何参数,你必须小心循环导入。就我而言,我只是设置了一个填充记录,因此父模型有一个预定义的来宾来表示已删除的来宾。有了新的 GDPR 规则,我们必须能够删除访客信息。
| 归档时间: |
|
| 查看次数: |
3574 次 |
| 最近记录: |