2012-02-18 5 views
0

私はModelControllerというクラスを構築しています。このクラスには、別のModelクラスをラップすることができるメソッドがたくさんあります。これは私のデータベース抽象化です。サブクラスの振る舞いをカスタマイズする方法、またはサブクラス化を特別な方法で行う方法はありますか?

私はそうのようModelControllerにクラスメソッドを定義することができるようにしたい:

ArticleModel(Model): 
    pass 

そして、このような何か:

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

そして、このようなモデルのクラスを持っている

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

コントローラのモデルクラスをサブクラス化してmixinパターンのようなものですが、モデルをコントローラのクラス属性にしたいのは、このクラスをcherrypyメソッドのディスパッチャーにマウントするときに、HTTP経由でいくつかのメソッドを誤って公開する危険性がありません。そんな感じ。

多分、私は何か根本的に非パイソン的であるか、何らかの誤謬をしています。私は '魔法'をしようとしていますか?

編集:私はちょうど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クラスがあります:私はcherrypyにマウントされます私の実際のController、で、最終的にはその後

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

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

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

それから私はモデルを持つことができます

class ArticleController(): 
    class meta: 
    model = ArticleModel 

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

    index.exposed = True 

はこれです悪の?それは十分ではない、魔法ですか? Rubyのルーツが表示されていますか?この時点から、新しいモデルとコントローラを定義するだけです。コントローラのメタクラスにmodel属性を定義することを忘れた場合、マウントされたメソッドがモデルのものを呼び出そうとすると、エラーがスローされます。

+0

...ありません...メタクラス... –

+0

ちなみに、*メタクラス私が持っているだろうか*ですそれをやった。 –

関連する問題