我有一個模型(事件),它有一個指向用戶模型(事件的所有者)的外鍵。 這個用戶可以邀請其他用戶,使用下面的ManyToManyField:
。 invites = models.ManyToManyField(
User, related_name=" invited_users",
verbose_name=_("Invited Users"), blank=True)
)
這個邀請欄位會生成一個簡單的表格,包含ID、event_id和user_id。
如果事件所有者洗掉了他的組態檔,我不希望事件被洗掉,而是將所有權傳遞給第一個被邀請的用戶。
所以我想出了這個函式:
def get_new_owner()。
try:
invited_users = Event.objects.get(id=id).Invites. order_by("-id").filter(is_active=True)
if invited_users.exists()。
return invited_users.first()
else:
Event.objects.get(id=id).delete()
exceptObjectDoesNotExist。
通過。
這將找到事件實體,并回傳按邀請表ID排序的活躍的被邀請用戶,因此我可以得到這個查詢集的第一項,它對應于第一個被邀請的用戶。
為了在用戶被洗掉時運行該函式,我使用了on_delete=models.SET:
。 owner = models.ForeignKey(User, related_name='evmt_owner', verbose_name=_("Owner"), on_delete=models.SET(get_new_owner() )
然后我遇到了一些問題:
有什么想法嗎?
uj5u.com熱心網友回復:
首先我們可以為Owner欄位定義一個策略,它將用被更新的物件來呼叫這個函式。我們可以定義這種洗掉,例如在<i.app_name/deletion.py檔案中:
# 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
你應該向SET傳遞一個callable,而不是呼叫這個函式,所以你可以這樣實作:
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)。
# .../span>
owner = models.ForeignKey(
settings.AUTH_USER_MODEL,
related_name='own_events'。
verbose_name=_('Owner')。
on_delete=models.SET_WITH(get_new_owner)
)
在這里,我們因此會看一下邀請函,以找到一個用戶來轉移物件。也許你需要在你的get_new_owner中把事件的當前.owner從.inivites的集合中排除。
正如@AbdulAzizBarkat所說,我們可以使用CASCADE而不是明確地洗掉Event物件,因為這將避免無限的遞回,一個User的洗掉觸發了一個Event的洗掉,而這個User的洗掉可能觸發一個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改寫為:
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: # 嚴格來說不是必須的,但顯式比隱式更重要。
return None
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/310473.html
標籤:
上一篇:如何使用IDE和Java-jar命令,在springboot應用程式中讀取資源檔案夾中的檔案?
下一篇:我必須提供兩次引數arr,一次是在Sorting(arr)中,另一次是在quicksort(arr)中,我怎樣才能只用arr重寫代碼?
