2013-06-23 22 views
4

這是一個後續問題:Cant get post_save to work in Django多對多領域同時使用信號來檢測保存在Django操作對象未顯示

我的型號是:

class Car(models.Model): 
    name = models.CharField(max_length=50) 
    ... 
    some other attributes of Car 
    ... 

class Person(models.Model): 
    car = models.ManyToManyField(Car) 
    name = models.CharField(max_lenght=100) 
    ... 
    Some other attributes of Person 
    ... 


class License(models.Model): 
    person = models.ForeignKey(Person) 
    ... 
    Other attributes of License 
    ... 

信號處理程序:

def signal_handler(sender, **kwargs): 
    print 'Person saved!' 
    generate_license() 

post_save.connect(signal_handler, sender=Person, dispatch_uid="Unique person") 

的意圖:創建Person的實例時,我想生成一個License對象。因此,我篩選出添加到許可證中的最後一個元組,然後使用其內容來生成許可證實例。

def generate_license(): 
    import pdb 
    pdb.set_trace() 
    man = Person.objects.filter().order_by('-time_added')[:1][0] # Restricting the filter to one query and then taking the value at the 0th index. order_by '-time_added' gives the latest tuple at the top. 
    license = License.objects.create(...Info about car, person...) 

的錯誤:

一個例子: 說Car有3個實例:

  1. BMW
  2. FERRARI
  3. LAMBORGHINI

現在,當我從管理,例如添加人的實例:

percar = BMW, FERRARIname = Bob 一個實例當我點擊管理saveset_trace()開始。所以在之後的generate_license查詢:

pdb,執行查詢的時候,我嘗試打印出per.car.all()但它給了我[],當我嘗試打印出per.name,它打印出來Bob。所以我真的不知道如何保存per.nameper.car沒有。

而且,當請求完成後,這是我在pdb按下c,我再次點擊保存爲同一個實例,這個時候它會讀取per.car.all()完美而如果在保存之前,我加LAMBORGHINI,那隻能說明up BMWFERRARI。所以我猜想的是many-to-many這個字段遲來了。雖然我不能指出原因。需要一些幫助。我錯過了什麼嗎?

問題:有沒有一種具體的方法可以從create signal中識別update signal?我的意思是我不想在每次更新數據時都生成新的License。只有在創建數據時纔會生成新的License。那麼,如何區分updatesave信號呢?

回答

2

post_save不適用於m2m字段。您必須使用m2m_changed signal

事情是這樣的:

def my_m2m_signal(sender, **kwargs): 
    action = kwargs.get('action') 
    if action == 'post_add': 
     print 'post_add is activated on m2m' 

signals.m2m_changed.connect(my_m2m_signal, sender=Person.car.through) 
+0

哦,是的。我曾在django-docs中讀過這個。但似乎我在看着它。 :( –

+0

所以,如果我發送一個'm2m_changed',我怎麼檢測到'post_save'和'm2m_changed'都已經收到?因爲只有這樣我才能生成一個License實例。 –

+0

我剛更新了答案..你需要聽取發送到信號中的'action'屬性 – karthikr