2014-02-19 12 views
0

我正在建立一個雲系統,我有兩個應用程序, 服務器應用程序,其中包括全部功能和客戶端應用程序,其中只包括輸入法, 所以我是在客戶分支安裝客戶端應用程序作爲本地應用程序,最好的做法,以覆蓋django模型中的保存方法是異步使用芹菜

我希望在本地保存模型之後覆蓋應用程序中的任何模型,我將調用一個芹菜任務以將該模型添加到隊列中以確保它將到達,即使互聯網關閉,我會做重試,直到互聯網起牀,

現在我想最好的做法有一個通用的方式來做到任何模型

我有兩個選項

1-壓倒一切的節省這樣

def save(self, *args, **kwargs): 
    super(Model, self).save(*args, **kwargs) 
    save_task.delay(self) 

方法或這樣

post_save.connect(save-task.delay, sender=Model) 

哪一個是最好的做法,我可以使其泛型使用的信號對於這個項目的所有模型?

+1

看來,在您將我的答案標記爲正確之後的一段時間,您爲此打開了一筆賞金。我很想知道我的答案中缺少什麼,也許會嘗試自己贏得獎勵。 – yuvi

回答

7

.save()只是一堆接一個地執行的信號。這裏的過程縮短版從the documentation

  1. 發出預保存信號。 [...]

  2. 預處理數據。 [...]大多數領域沒有預處理[...]只用於具有特殊行爲的領域[...] 文檔尚未包含此 「特殊行爲。「

  3. 準備數據庫的數據。要求每個字段以數據類型的形式提供其當前值,該數據類型可寫入數據庫 。大多數字段不需要數據準備整數和字符串 '準備寫入'作爲一個Python對象[...]複雜的數據類型經常 需要一些修改。 [...]

  4. 將數據插入數據庫。 [...]

  5. 發出保存後信號。 [...]

在你的情況,你不這樣做在這個過程中間什麼。您只需在模型保存後執行此操作。所以不需要使用信號。

現在你真正要問的是如何確保一個任務最終被執行。好:

  1. 我敢肯定,你可以解決這個使用芹菜
  2. 你應該掛鉤應用到一個數據庫(如果你能),不保存在本地的東西,然後更新服務器,這可能會變得醜陋。

,如果你真的認爲有互聯網的下降之類的東西一個公平的機會,而你肯定有沒有更好的辦法來鏈接您的應用程序,我建議你添加一個新模式跟蹤已更新的內容。事情是這樣的:

class Track(models.Model): 
    modelname = models.CharField(max_length=20) 
    f_pk = models.IntegerField() 
    sent = models.BooleanField() 

    def get_obj(self): 
     try: 
      # we want to do modelname.objects.get(pk=self.f_pk), so: 
      return getattr(getattr(self.modelname, 'objects'), 'get')(pk=self.f_pk) 
     except: 
      return False 

注意如何我不會將其鏈接到某個模型,而是給它的工具對任何模型獲取你該死的好請。然後,對於每個模型,你要保持跟蹤,你補充一點:

class myModel(models.Model): 
    ... 
    def save(self, *args, **kwargs): 
     super(Model, self).save(*args, **kwargs) 
     t = Track(modelname=self.__class__.__name__, f_pk=self.pk, sent=False) 
     t.save() 

然後scheduale任務,將Track對象與sent=False,並嘗試將其保存:

unsent = Track.objects.filter(sent=False) 
for t in unsent: 
    obj = t.get_obj() 
    # check if this object exists on the server too 
    # if so: 
     t.sent = True 
     t.save() 

附:

記得我提到的事情可能會變醜嗎?自從我發佈這個版本以來,我就已經有了一些時間,我已經看到了。請注意,我如何使用pk和modelname來確定模型是否保存在兩個地方,對嗎? 但是,pk's(默認在django中)是一個自動遞增的字段。如果應用程序在兩個地方運行,或者即使您在本地運行,並且發生一次錯誤,也會比pks ca快速失去同步。

說我保存了一次對象,它在本地和服務器上都獲得1的pk。

local    server 
name pk ++ name pk 
obj1 1 ++ obj1 1 

然後我保存另一個,但互聯網出現故障。

local    server 
name pk ++ name pk 
obj1 1 ++ obj1 1 
obj2 2 ++ 

下次啓動時,我添加了一個新對象,但是這發生在調度任務運行之前。所以現在我的本地數據庫有3個對象,而我的服務器有2個,那些有不同的PK,得到它?

local    server 
name pk ++ name pk 
obj1 1 ++ obj1 1 
obj2 2 ++ obj3 2 
obj3 3 ++ 

,後schedualed任務的運行,我們也會有這樣的:

local    server 
name pk ++ name pk 
obj1 1 ++ obj1 1 
obj2 2 ++ obj3 2 
obj3 3 ++ obj2 3 

瞭解如何輕鬆這種可能失控的?爲了解決這個問題,每個跟蹤的模型將有一些獨特的標識符,你需要以某種方式告訴Track模型如何遵循它。這很令人頭疼。最好不要在本地保存東西,而是把所有東西都放在一起

+0

這正是我正在尋找的,我將創建一個模型可以接受泛型類型,如管理員logentry,將記錄所有保存的實例,如果這個對象的狀態不發送,我會發送它然後更新日誌扔芹菜,感謝兄弟 – mohd

相關問題