2013-07-17 28 views
2

我試圖模仿Django的unique_together功能保證在數據存儲的獨特性,但我似乎無法得到它直NDB模式:使用自定義KEY_NAME

class MyClass(ndb.Model): 
    name = 'name' 
    surname = 'surname' 
    phone = 'phone' 

    def get_unique_key(self): 
     return self.name + "|" + self.surname + "|" + self.phone 

「是啊,很容易」

根據this post中接受的答案,只需在obj構造函數中分配id param就足夠了。但我不想在視圖中處理這個問題。理想情況下,我應該這樣做:

object = MyClass() 
object = object.custom_populating_method(form.cleaned_data) 
object.id = object.get_unique_key() 
object.put() 

甚至更​​好,地方,在_pre_put_hook,從而使id會保存之前被設置爲過去的事(或許做一下檢查跨越強制執行數據的唯一性數據存儲)。

顯然,我錯了。實現這一目標的唯一途徑是通過黑客的觀點:

unique_id = "|" + form.cleaned_data['bla'] + "|" + form.cleaned_data ... 
object = MyClass(id=unique_id) 

這是可怕的和完全錯誤的(因爲必須還考察了看法每次更改模型的要求)。另外,我最終會做一些醜陋的調用來獲取一些相關的數據。 我花了太多的時間,可能在這個問題上看到退出,我真的很希望我在這裏錯過了一些明顯的東西,但我無法真正找到任何好的例子,也沒有圍繞這個主題的適當文檔。有沒有人有類似的暗示或經驗?

tl; dr:有沒有一種很好的方式來實現這一點,而不添加不必要的代碼到我的意見?

(我「使用」 Django和NDB對數據存儲模式)

感謝

+0

您是否嘗試過實現自己的構造函數? – dragonx

+0

好吧,我嘗試實現我自己的__init__方法(有和沒有調用超級構造函數)沒有成功 –

+0

你不想覆蓋init,除非你真的知道你在做什麼。在創建實體之前,使用工廠(類方法)構造創建密鑰的實體。看一個例子 –

回答

2

使用工廠或類方法構造實例。

class MyClass(ndb.Model): 
    name = ndb.StringProperty() 
    surname = ndb.StringProperty() 
    phone = ndb.StringProperty() 

    @staticmethod 
    def get_unique_key(name,surname,phone): 
     return '|'.join((name,surname,phone)) 

    @classmethod 
    @transactional 
    def create_entity(cls,keyname,name,surname,phone): 
     key = ndb.Key(cls, cls.get_uniquekey()) 
     ent = key.get() 
     if ent: 
      raise SomeDuplicateError() 
     else: 
      ent = cls(key=key, name=name,surname=surname,phone=phone) 
      ent.put() 

newobj = MyClass.create_entity(somename,somesurname,somephone)

這樣做,這樣可以讓你也能確保關鍵是由肌酸的關鍵和特林第一獲取它的獨特。

+0

這樣做了,謝謝! –

+0

我們稍後再說一下用戶的電話更改(僅重用該示例,我的用例有點不同)。我們把()一個新的電話號碼。但現在密鑰並不反映ndb上存儲的數據。有人試圖從第一次再次添加相同的值:(姓名,電話)。它失敗了,因爲之前已經使用過這個組合,但是如果您搜索第一個電話號碼,則什麼也找不到。 爲了避免這種情況,我考慮刪除密鑰並創建一個新的obj,但是我忽略了其他模型可能對它的引用。關於如何做到這一點的任何想法仍然使用關鍵的不統一? – alfetopito

0

我認爲你可以做到這一點,如果您分配了整個key,而不僅僅是id

object = MyClass() 
object = object.custom_populating_method(form.cleaned_data) 
object.key = ndb.Key(MyClass, object.get_unique_key()) 
object.put() 
相關問題