簡體   English   中英

Django多對多字段復制

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM