2017-01-19 28 views
1

我有一個模型M包含三個manytomanyfields(a,b,c)django中的三個不同的模型。dajngo,處理m2m多個模型的變化信號ManyToManyField

class M (models.Model): 
      name = models.CharField() 
      a = models.ManyToManyField(A) 
      b = models.ManyToManyField(B) 
      c = models.ManyToManyField(C) 

知道,我想處理我的模型M上的任何更改,並相應地發送一個HttpRequest到一個URL。 你在知道後保存模型M的信號的屬性的值,b和c尚未設定,因爲他們將節省模型當M已經完成設置。(ManyToManyField的規則)

我寫我的模型來處理任何變化的單一處理器(創建新實例或更新場/場)

@receiver(post_save, sender=M) 
    @receiver(m2m_changed, sender=M.a.through) 
    @receiver(m2m_changed, sender=M.b.through) 
    @receiver(m2m_changed, sender=M.c.through) 
    def M_changes_handler(sender, **kwargs): 
      is_instance_set_compeletly(kwargs['instance']): 
       #send_and_HttpRequest(url, data = instance) 


    def is_instance_set_compeletly(kwargs['instance']): 
      if M.a.all() is not None and M.b.all() is not None and 
       M.c.all()is not None 
      flag = True 
      else: 
      flag = False 
      return flag 

現在考慮的更新請求(更改所有字段)的模型M將發出信號,所有字段a,b和c;所以三個httpRequests會通過三個不同版本的實例發送給我的發件人!另一方面,當用戶只是改變模型M的字段例如b時,該函數將只發送一個httpRequest。

我要動態地處理這個問題,只是每次發送任何變化的TYPE一個請求我的模型M 我在想,如果有人能幫助我:)

*注意上面的代碼僅僅是一個草案並可能包含語法錯誤,所以忽略它們;)

更新:我的問題解決了! 保存包含m2mfields的模型的過程非常有用! 首先,不是m2m字段的M字段輸入例如在調用post_save之前已經設置了char域,外鍵等。所以在post_save中,它們的值會更新 雖然m2mfields不會被設置,直到模型的保存完成。所謂設置m2mfields 的唯一途徑然後m2mchange信號有你的模型的更新版本是在admin.py overridding形式保存,因爲「形式保存」將完成所有m2mfields已設置

+0

你可以添加一個例子你是如何解決你的問題? –

回答

0

後就可以被稱爲保存M的前一個實例,並在post_save中用新的M檢查字段根據您可以發送的請求進行更改。

+0

感謝您的回覆,不幸的是,這並不適用於我的情況,因爲當包含由post_save信號收到的m2mfields的模型實例與前一個值具有相同的值時,直到m2mfields將在post_save後保存! – Atefeh

0

解決方案: 對於所有的堆棧溢出用戶和尊敬的布萊克吉布斯 如果模型包含多對多字段和您要訪問已保存記錄的所有數據,您將無法訪問這些M2M領域,因爲他們將在完成後保存保存模型的過程(在我的示例中考慮M),然後將該Id分配給其他自創的m2m表,將該Id綁定到m2m字段(例如,在我的示例中爲A)。所以在這種情況下,重寫admin.py中的模型的保存方法不起作用。 我只是重寫我的形式保存功能Forms.py

類MForm(forms.ModelForm):

class Meta: 
     model = M   
     exclude = [] 
def save(self, commit=True): 
    query = "" 
    old_instance = super(MForm, self).save(commit=False)# if you need the old instance 

#otherwise回報超(MForm,個體經營).save(提交= TRUE)

instance = super(MForm,self).save(commit=True) 

在這種情況下,「實例」真的完全保存,您可以通過使用訪問M2M領域「所有()」

希望它幫助!