デコレータとセッションを含むジャンゴクラスビュー
質問
djangoビューの一部を関数ベースのビューからクラスベースのビューに変換しようとしていますが、小さな問題に遭遇しました。
私のオブジェクト指向はやや弱く、問題はどこに向かっているのかわからなくなっていることだと思います。
ビューに必要なカスタムログインデコレータがあるので、...
まず、この例のViewクラスがあります http://www.djangosnippets.org/snippets/760/
この場合、ビュークラスは次のようになります...
class TopSecretPage(View):
@custom_login
def __call__(self, request, **kwargs):
#bla bla view stuff...
pass
問題は、デコレーターが何らかの理由でrequest.sessionにアクセスできないことです...
私のデコレータは次のようになります...
def myuser_login_required(f):
def wrap(request, *args, **kwargs):
# this check the session if userid key exist,
# if not it will redirect to login page
if 'field' not in request.session.keys():
return wrap
私が見逃しているのは簡単なことだと思うので、皆さんの忍耐に感謝します!
更新: わかりましたので、ここに私が得るエラーがあります...
" ViewDoesNotExist:モジュールprojectname.application.viewsでTopSecretPageを試しました。エラー:タイプオブジェクト 'TopSecretPage'には属性 'session'"
がありませんこのように見えるようにデコレータも簡略化しました。...
def myuser_login_required(request, *args, **kwargs):
# this check the session if userid key exist,
# if not it will redirect to login page
if 'username' not in request.session.keys():
return HttpResponseRedirect(reverse("login-page"))
return True
解決
問題は、ラッパーが" request"を期待していることです。最初の引数としてですが、クラスのメソッドは常に「自己」を取ります。最初の引数として。したがって、デコレータでは、リクエストオブジェクトは実際にはTopSecretPage自体であると考えられます。
Vinayまたはartranのソリューションのいずれかが機能するはずなので、繰り返しはしません。問題のより明確な説明が役立つかもしれないと思った。
他のヒント
クラスベースのビューメソッドに適用されるデコレータに対してこれを行う正しい方法は、 django.utils.decorators.method_decorator()
を使用することです。 method_decorator()がいつ導入されたのかはわかりませんが、Django 1.2の例/更新リリースノート。次のように使用します:
from django.utils.decorators import method_decorator
class TopSecretPage(View):
@method_decorator(custom_login)
def __call__(self, request, **kwargs):
#bla bla view stuff...
pass
この問題は、前で発生しました。役に立つソリューションが含まれています。
更新:デコレータを使用したメソッドの例:
class ContentView(View):
# the thing in on_method() is the actual Django decorator
#here are two examples
@on_method(cache_page(60*5))
@on_method(cache_control(max_age=60*5))
def get(self, request, slug): # this is the decorated method
pass #in here, you access request normally
ビューでデコレータを使用する代わりに、URLをデコレートできます。
たとえばurls.pyの場合:
from my_decorators import myuser_login_required
from my_views import TopSecretPage
urlpatterns = patterns('',
(r'^whatever-the-url-is/
それで少し遊ぶ必要があるかもしれませんが、それはほぼ正しいです。
, myuser_login_required(TopSecretPage), {}),
)
それで少し遊ぶ必要があるかもしれませんが、それはほぼ正しいです。
これは実質的に Djangoの複製-正しい方法CBVデコレータに引数を渡しますか? これに対処する正しい方法を説明しています。 django 1.9でこれを行う正しい方法は次のとおりです。
@method_decorator(myuser_login_required(), name='dispatch')
class TopSecretPage(View):
..