2013-10-11 39 views
0

我正在編寫一個大的項目,這個項目是由其他人編寫(並放棄)的,並且需要一種方法來使每個對.all()的調用都爲特定模型檢查一個布爾值。整個項目實際上有數千個電話,所以我一直在尋找一種方法來避免重寫它們。是否可以重寫Model或Polymodel的all()方法以包含過濾器?

我的想法是重寫.all()方法,用過濾器調用父.all()。這是我第一次使用Google App Engine,所以我一直在做很多猜測工作。

我以爲我可以像這樣開始:

class Bob(polymodel.PolyModel): 
    stuff = db.StringProperty() 
    active = db.BooleanProperty(default=False) 
    def all(self, keys_only=False): 
     super(Bob,self).all() 

但是當我嘗試這樣的呼籲:

joes = Bob.all() 
    for joe in joes: 
     self.response.write(joe.active) 

我得到這個:

類型錯誤:未綁定的方法all()必須以Bob實例作爲第一個參數被調用(取而代之)

這是我在stackoverflow上的第一篇文章,所以我希望我已經做到了這一點。任何幫助將不勝感激。

SOLUTION(後來加入)

class Bob(db.Model): 
    stuff = db.StringProperty() 
    active = db.BooleanProperty(default=False) 
    @classmethod 
    def all(cls, keys_only=False): 
     if keys_only == True: 
      qry = super(Bob,cls).all(keys_only=True) 
      qry.filter('active =', True) 
      return qry 
     else: 
      qry = super(Bob,cls).all(keys_only=False) 
      qry.filter('active =', True) 
      return qry 
+0

您在解決方案上的縮進不正確。此外,爲什麼要將'if keys_only = True:'條件放入。只需將keys_only傳遞給all()調用。即'所有(keys_only = keys_only)'按照我的答案。更少的代碼來測試並保持最新狀態。 –

+0

對不起,剛纔回來了...它沒有正確粘貼,我當時沒有注意到。我會修正縮進。出於某種原因,儘管我認爲它應該如此,但你的解決方案並不奏效。 if塊是我的解決方法,你的方法不工作。 – user2872818

回答

1

首先你有一個基本的Python類/方法的問題。如錯誤所示TypeError: unbound method all() must be called with Bob instance as first argument (got nothing instead)

您正在調用all()而不是實例,但您已將覆蓋的all()定義爲實例方法。

應該

@classmethod 
def all(cls, keys_only=False): 
    qry = super(Bob,cls).all(keys_only=keys_only) 
    qry.filter(<some filter>) 
    return qry 

在你的代碼中不返回任何東西還要注意。 all()返回一個查詢對象,你也可以應用更多的過濾器。

我不會覆蓋所有和應用濾鏡,因爲你將有效地阻止你能夠使用裸所有()

創建另一個類方法,即。 filtered_all()並使用它以便可以保留all()。

例如

@classmethod 
def filtered_all(cls,keys_only=False) 
    qry = cls.all(keys_only) 
    qry.filter('some boolean operation') 
    return qry 

另外,如果你沒有對db的投資,我個人認爲你應該切換到ndb。

+0

如果你重載'all'(而不是像第二個例子中那樣增加一個新的'filtered_all'),你可能確實需要調用'super(Bob,cls).all()',因爲'cls.all() '是無限遞歸的(所以當它遇到系統遞歸限制時會引發'RuntimeError')。 – Blckknght

+0

好點忘記;-)將編輯 –

+0

感謝球員,我將無法測試代碼,直到星期一,但它看起來不錯。可悲的是,我在技術上沒有發言權......這個項目多年來我一直在努力,但他們失去了(解僱了)所有原始開發人員,我的僱主被約定完成該項目。 我可能會寫一種方式來訪問所有沒有過濾器,但在這個項目中,這個特定的模型將總是需要檢查它的活動和它已經寫入all()到處。 再次感謝:) – user2872818

0

Tim的答案是對的,但是因爲你只有一個類,或者少數幾個類,你可以很容易地在Bob.all()上進行搜索和替換,並將其更改爲Bob.filter(yournewboolean = True) 。

任何體面的文本編輯器或IDE都能夠在一分鐘內爲您做到這一點。

+0

謝謝,但是一個簡單的查找和替換將不起作用,因爲一些零件已經連接了過濾器,並且有數千個實例...如果替換會導致問題,則可能很難排除故障。我正在尋求的解決方案(看起來像其他答案提供的解決方案)將更容易編寫和排除故障。但在大多數情況下,我會使用這種方法:) – user2872818