[英]Django many-to-many field copy
我有一個Django模型,有2個多對多字段。 當我從管理界面保存模型時,我需要檢查第二個字段是否為空白,如果它是空白的,那么我需要將第一個現場的項目復制到第二個。 我怎樣才能做到這一點?
UPDATE
馬修的答案看起來似乎很有效但我在復制字段后無法保存實例。 我嘗試過instance.save()但沒有任何成功。
您可以使用保存后信號。 這看起來可能是處理您需求的最佳方式:獎勵是它也可以在管理員之外工作。
@models.signals.post_save(sender=MyModel)
def duplicate_missing_field(sender, instance, **kwargs):
if not instance.my_second_m2m.count():
instance.my_second_m2m.add(*instance.my_first_m2m.all())
# or *instance.my_first_m2m.values_list('pk', flat=True), I think
我的代碼可能不太正確:你想要閱讀django中的信號。
要使用的信號不是post_save
,而是m2m_changed
,它在模型保存到數據庫后發送很多。
@models.signals.m2m_changed(sender=MyModel.second_m2m.through)
def duplicate_other_on_this_if_empty(sender, instance, action, reverse, model, pk_set, **kwargs):
# just before adding a possibly empty set in "second_m2m", check and populate.
if action == 'pre_add' and not pk_set:
instance.__was_empty = True
pk_set.update(instance.first_m2m.values_list('pk', flat=True))
@models.signals.m2m_changed(sender=MyModel.first_m2m.through)
def duplicate_this_on_other_if_empty(sender, instance, action, reverse, model, pk_set, **kwargs):
# Just in case the "first_m2m" signals are sent after the other
# so the actual "population" of the "second_m2m" is wrong:
if action == 'post_add' and not pk_set and getattr(instance, '__was_empty'):
instance.second_m2m = list(pk_set)
delattr(instance, '__was_empty')
編輯:下一個代碼更簡單,並基於模型定義的新知識
在您的代碼中,'first_m2m'信號在'second_m2m'之前發送(它實際上取決於您的模型定義)。 因此,我們可以假設當接收到'second_m2m'信號時,'first_m2m'已經填充了當前數據。
這讓我們更開心,因為現在你只需要檢查m2m-pre-add:
@models.signals.m2m_changed(sender=MyModel.second_m2m.through)
def duplicate_other_on_this_if_empty(sender, instance, action, reverse, model, pk_set, **kwargs):
# just before adding a possibly empty set in "second_m2m", check and populate.
if action == 'pre_add' and not pk_set:
pk_set.update(instance.first_m2m.values_list('pk', flat=True))
您可以覆蓋clean方法以進行額外驗證,因此如果第二個many2many為空,則可以設置默認值,例如:
def clean(self):
super(MyClassModel, self).clean()
if not self.MySecondMany2Many:
# fill data
你應該在你的類里面的models.py中設置這段代碼。 如果clean不起作用,因為需要保存模型,你也可以覆蓋保存功能,這是相同的過程。
我沒有測試它,我認為你不能檢查many2many字段是否空白,但你應該明白:)
你可以從這里看到admin save override定義,只需覆蓋它並檢查相關字段是否為空,如果是,保存對象,從第二個M2M獲取相關數據並將其設置為第一個M2M並再次保存...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.