2012-02-18 38 views
0

假設我正在創建一個名爲ModelController的類。我想這個類有一堆方法可以包裝一個單獨的Model類,這是我的數據庫抽象。如何自定義子類行爲或需要以特定方式進行子類化?

我希望能夠定義一個類的方法上ModelController像這樣:

ModelController(): 
    @classmethod 
    def list(cls): 
    cls.model.list() 
    @classmethod 
    def byName(cls, name): 
    return cls.model(name) 

而且具有示範類是這樣的:

ArticleModel(Model): 
    pass 

然後做這樣的事情:

ArticleModelController(ModelController): 
    # ??? maybe: 
    # model = ArticleModel 

我想我可以繼承我的模型類的控制器,然後有某種mixin模式,但我希望模型成爲控制器的類屬性的原因是我真的不希望在使用cherrypy方法調度程序掛載此類時,不希望通過HTTP意外暴露它的一些方法,或者類似的東西。

也許我正在做一些根本性的非pythonic或犯了某種謬誤。我想做'魔術'嗎?

編輯:我只記得我過去的Django及其ModelForms。他們的工作是這樣的:

class ArticleForm(ModelForm): 
    class Meta: 
     model = Article 

也許這是我應該看的。是否有可能驗證這個'model'屬性是否定義,如果某些東西是未定義的,則拋出一個錯誤?

回答

2

是元類:

class ModelControllerMetaclass(type): 
    def __init__(cls, name, bases, dct): 
    if 'options' not in dct or not hasattr(dct['options'], 'model'): 
     raise RuntimeError('You accidentally the model!') 
    dct['_model'] = dct['options'].model 
    # Some more manipulation of dct['options'] 
    del dct['options'] 
    type.__init__(cls, name, bases, dct) 

class ModelController(object): 
    __metaclass__ = ModelControllerMetaclass 
    class options: 
    model = None 

class ArticleModelController(ModelController): 
    class options: 
    model = 'Some model goes here' 

class InvalidModelController(ModelController): 
    pass 

而且一旦運行:

$ python t.py 
Traceback (most recent call last): 
    File "t.py", line 19, in <module> 
    class InvalidModelController(ModelController): 
    File "t.py", line 4, in __init__ 
    raise RuntimeError('You accidentally the model!') 
RuntimeError: You accidentally the model! 
0

我想我已經想通了。我認爲元類可能是解決方案,但我會閱讀很多東西,說你可能做錯了什麼,除非你確實知道你需要一個元類。儘管如此,它給了我想要的確切行爲。這是我的ModelController類:

class ModelController(): 
    @classmethod 
    def list(cls): 
    return cls.meta.model.list() 

    def __init__(self): 
    self.model = self.__class__.meta.model 

然後我就可以有一個模型:

class ArticleModel(): 
    @classmethod 
    def list(cls): 
    # logic to retrieve the list of things fitting this class 

於是最後,在我的實際Controller,我將在cherrypy安裝:

class ArticleController(): 
    class meta: 
    model = ArticleModel 

    def index(self): 
    article_list = self.model.list() 
    return render(article_list) 

    index.exposed = True 

這是邪惡?這是不是很神奇,不夠明確?我的Ruby根目錄是否顯示?從這一點開始,我需要做的就是定義新的模型和控制器,如果我忘記在我的控制器的元類中定義一個model屬性,當我的掛載方法嘗試調用模型上的東西時,它將引發錯誤。

+0

那是......不是......元類...... – 2012-02-18 04:18:47

+0

順便說一句,元類*爲*我怎麼會有完成了。 – 2012-02-18 04:19:16

相關問題