首先我们可以定义一个策略Owner
将使用已更新的对象调用函数的字段。我们可以定义这样的删除,例如在<i.app_name/deletion.py
file:
# app_name/deletion.py
def SET_WITH(value):
if callable(value):
def set_with_delete(collector, field, sub_objs, using):
for obj in sub_objs:
collector.add_field_update(field, value(obj), [obj])
else:
def set_with_delete(collector, field, sub_objs, using):
collector.add_field_update(field, value, sub_objs)
set_with_delete.deconstruct = lambda: ('app_name.SET_WITH', (value,), {})
return set_with_delete
你应该通过一个callable to SET
,不调用该函数,因此您将其实现为:
from django.conf import settings
from django.db.models import Q
from app_name.deletion import SET_WITH
def get_new_owner(event):
invited_users = event.invites.order_by(
'eventinvites__id'
).filter(~Q(pk=event.owner_id), is_active=True).first()
if invited_users is not None:
return invited_users
else:
event.delete()
class Event(models.Model):
# …
owner = models.ForeignKey(
settings.AUTH_USER_MODEL,
related_name='owned_events',
verbose_name=_('Owner'),
on_delete=models.SET_WITH(get_new_owner)
)
因此,在这里我们将查看邀请以查找将对象转移到的用户。也许您需要排除当前的.owner
您的事件的get_new_owner
从收集的.inivites
.
我们可以,如@AbdulAzizBarkat 说 https://stackoverflow.com/questions/69207710/access-model-instance-inside-model-field/69207958?noredirect=1#comment122322044_69207958,使用 CASCADE 比显式删除更好Event
object ,因为这将避免无限递归User
删除会触发Event
删除可能会触发User
删除:目前这是不可能的,但稍后如果实现额外的逻辑,可能会出现这种情况。在这种情况下,我们可以使用:
from django.db.models import CASCADE
def SET_WITH(value):
if callable(value):
def set_with_delete(collector, field, sub_objs, using):
for obj in sub_objs:
val = value(obj)
if val is None:
CASCADE(collector, field, [obj], using)
else:
collector.add_field_update(field, val, [obj])
else:
def set_with_delete(collector, field, sub_objs, using):
collector.add_field_update(field, value, sub_objs)
set_with_delete.deconstruct = lambda: ('app_name.SET_WITH', (value,), {})
return set_with_delete
并重写get_new_owner
to:
def get_new_owner(event):
invited_users = event.invites.order_by(
'eventinvites__id'
).filter(~Q(pk=event.owner_id), is_active=True).first()
if invited_users is not None:
return invited_users
else: # strictly speaking not necessary, but explicit over implicit
return None