2011-05-10 93 views
0

我有一個模型(補丁)它有一個作者字段,我需要生成幾個報告,總是過濾出作者不包含字符串'@ example.com'的行。鑑於補丁是在一個單獨的django應用程序中定義的,我不想更改,我的想法是創建一個DB視圖(例如,ExampleComPatch,使用非託管模型類訪問),可以過濾掉所有行我不感興趣,然後將報告方法放在新模型類下。如何將所有字段定義從一個模型類複製到另一個模型類?

爲了避免代碼重複,我讓我的新模型類從Patch繼承。這工作正常,只有一對夫婦的注意事項:

  1. 我認爲需要有一個額外的「patch_ptr_id」一個在補丁中定義的所有列加,因爲Django的認爲我想真正的繼承在DB以及
  2. 由於這是一個非管理模型類,使用該視圖中的測試需要創建手動

然而,由於Django的認爲我想真正的繼承,每當我刪除補丁的一個實例,它結束了貫通進入其所有子對象(例如,連接到它的ExampleComPatch中的行),這意味着與ExampleComPatch無關的測試現在可以是n如果需要從修補程序表中刪除()行,則需要手動創建數據庫視圖。我想繼承可能不是最好的選擇,但我真的想避免代碼重複,所以我想知道是否有辦法將所有字段定義從Patch複製到ExampleComPatch。或者,甚至可能採用完全不同的方法,使我可以使用數據庫視圖(以降低報告方法的複雜性)和在補丁之外定義的報告方法,因爲它們在那裏沒有多大意義。

回答

1

代理模型是您的票。事情是這樣:

from somewhere import Patch 

class FilteredPatchManager(models.Manager): 
    def get_query_set(self, *args, **kwargs): 
     return super(FilteredPatchManager, self).get_query_set().exclude(author__contains='@example.com') 


class FilteredPatch(Patch) 
    objects = FilteredPatchManager() 

    class Meta: 
     proxy = True 

然後,使用FilteredPatch.objects進行查詢,而不是Patch.objects

+0

這正是我想要的;不能相信我沒有注意到關於繼承的文檔。謝謝! – 2011-05-10 21:18:00

0

我認爲你讓事情比他們需要的複雜得多。如果我理解正確的話,你想從一些標準的GET查詢排除某些對象 - 如果是這樣的話,你應該看看

Modifying initial Manager QuerySets

基本上,你可以自定義得到的查詢返回,就像這樣:

# First, define the Manager subclass. 
class PatchManger(models.Manager): 
    def get_query_set(self): 
     return super(PatchManager, self).get_query_set().exclude(author__contains='@example.com') 

# Then hook it into the Patch model explicitly. 
class Patch(models.Model): 
    author = models.CharField(max_length=100) 

    objects = PatchManager() # The custom manager. 

希望我理解正確你的問題......

乾杯,

馬丁

+0

這正是我想要編寫的報告方法的要求,但不是針對修補程序中的所有現有方法,因此它不起作用。另外,正如我所說,Patch是在一個單獨的django應用程序,我不能改變,所以我想在一個單獨的模型類(它的子類,在數據庫級過濾似乎是最好的選擇)。還是)感謝你的建議。 – 2011-05-10 20:51:52

0

爲什麼您需要繼承或複製代碼?您可以將模型導入當前應用程序並在必要時進行篩選 - 如果您願意,可以在應用程序中創建一個封裝篩選器的函數,因此您只需調用該函數即可返回篩選出的實例。

+0

我不希望的事情之一是不得不在多個地方進行篩選,所以通過在儘可能低的級別(DB)進行篩選,我不必在任何報告方法中進行篩選。這就是爲什麼我使用數據庫視圖進行訪問的原因,但是由於模型類具有與現有視圖完全相同的字段,因此我想在它們之間共享該代碼。 – 2011-05-10 20:46:19

相關問題