2017-06-26 6 views
1

私は複数のビューをすべてベースビューから継承しています。すべてのビューにはlogin_requiredデコレータが必要です。これをメソッドデコレータとして追加して、ベースビューを送出し、すべての子ビューにデコレータを追加する必要はありません。私はこれを達成できませんでした。クラスベースビューのディスパッチ時にlogin_requiredデコレータの継承

これは一般的に不可能ですか?私は何が欠けていますか?私は何を知っていないのですか?

class CoreView(CoreMixin,TemplateView): 
    pass 


class BaseView(CoreView): 

    @method_decorator(login_required) 
    def dispatch(self, request, *args, **kwargs): 
     return super(BaseView, self).dispatch(request, *args, **kwargs) 


class MyView(BaseView): 

    def dispatch(self, request, *args, **kwargs): 
     "Do Stuff" 

私は私の研究を行うことを試みたが、答えを見つけることができませんでした。ここで

は、私のコードの多少壊れたバージョンです。

私は現在django 1.8とpython 2.7を使用しています。

答えて

0

はそれを試してみてください。

def login_required_class(decorator): 
    def decorate(cls): 
     for attr in cls.__dict__: 
      if callable(getattr(cls, attr)): 
       setattr(cls, attr, decorator(getattr(cls, attr))) 
     return cls 
    return decorate 

@login_required_class(login_required) 
class CoreView(CoreMixin,TemplateView): 
    pass 

@login_required_class(login_required) 
class BaseView(CoreView): 

    def dispatch(self, request, *args, **kwargs): 
     return super(BaseView, self).dispatch(request, *args, **kwargs) 

@login_required_class(login_required) 
class MyView(BaseView): 

    def dispatch(self, request, *args, **kwargs): 
     "Do Stuff" 
+0

重複デコレータの数を最小限に抑えるソリューションを見つけることを望んでいました。私はまだすべての子ビューにデコレータを追加するので、これはそれを解決していないようです。 – jimfawkes

+0

'@ login_required'は要求を最初の引数として期待しますが、これはクラスの_every_ callableメンバにデコレータを追加します。これにより、最初の引数として要求を受け取っていない他の呼び出し可能な呼び出しに対してエラーが必ず発生します。 – knbk

2

そこには「直接的」な方法はありませんが、あなたはPython: Decorating a class method that is intended to be overwritten when inheritedで、いくつかの解決策を見つけることができます。

あなたはのように、dispatchにフックを使用することですために適応するのは簡単ですのみ1:

class CoreView(CoreMixin,TemplateView): 
    pass 


class BaseView(CoreView): 

    @method_decorator(login_required) 
    def dispatch(self, request, *args, **kwargs): 
     do_dispatch(self, request, *args, **kwargs) 
     return super(BaseView, self).dispatch(request, *args, **kwargs) 

    def do_dispatch(self, request, *args, **kwargs): 
     # This is the method we'll override 
     pass   


class MyView(BaseView): 

    def do_dispatch(self, request, *args, **kwargs): 
     "Do Stuff" 
1

あなたの答えは、マニュアルです。クラスベースのビューにはmixinsがあります。もしあなたがそれを見逃してもpermission requiredのために。

関連する問題