2011-07-17 1 views
1

私のアプリでは、現在のユーザーがLocationオブジェクトを作成していない場合は別のURLにリダイレクトするかどうかをチェックする次のデコレータをアプリケーションに持っています。デジタイザーへのパラメータとしてのDjangoパスモデル名

def location_required(f): 
    def wrap(request, *args, **kwargs): 
     locations = Location.objects.filter(user=request.user) 
     if locations.count() == 0: 
      return HttpResponseRedirect("/") 
     return f(request, *args, **kwargs) 
    wrap.__doc__=f.__doc__ 
    wrap.__name__=f.__name__ 
    return wrap 

他の多くのモデルで同様の機能を使用したいと考えています。いくつかのデコレータを作成するのではなく、パラメータとしてモデル名を渡すだけです(おそらくリダイレ​​クトするURLも)。

これは可能ですか?どのような変更が必要ですか?

アドバイスをいただければ幸いです。

ありがとうございました。

答えて

1

確実に可能です。私はここでやったすべてが、ラッピングの別の層を追加することです

def object_required(model_class, redirect_url): 
    def location_required(f): 
     def wrap(request, *args, **kwargs): 
      locations = model_class.objects.filter(user=request.user) 
      if locations.count() == 0: 
       return HttpResponseRedirect(redirect_url) 
      return f(request, *args, **kwargs) 
     wrap.__doc__=f.__doc__ 
     wrap.__name__=f.__name__ 
     return wrap 
    return location_required 

:それは、次の(未テスト)コードのようなものを探して終わるかもしれません。あなたのオリジナルのデコレータは、渡された関数fをカスタマイズしました。私の外側の層はあなたのデコレータをカスタマイズします。モデルクラスを扱う別の関数で、既存のデコレータを包むの

@object_required(Location, '/') 
def my_view_func(request) 
    #your view code 
+0

感謝を! – Dan

2

ガレスのアプローチをして、URLが正しいリダイレクト:あなたは、同じ方法でそれを使用します。私は、次の小さな変更を提案:

  • 使用exists()代わりにラップ機能を更新するために使用django.utils.functional.wrapsゼロ
  • count()を比較する代わりに、手動で__name____doc__を設定します。
  • ラップ関数の変数locationsは、任意のモデルインスタンスになる可能性があるため、名前が変更されました。

これは与える:ビューで

from django.utils.functional import wraps 

def object_required(model_class, redirect_url="/"): 
    # model_class and redirect_url are available to all inner functions 
    def decorator(f): 
     # this is called with f, the function being decorated 
     def wrapper(request, *args, **kwargs): 
      # this is called each time the real function is executed 
      instances = model_class.objects.filter(user=request.user) 
      if not instances.exists(): 
       return HttpResponseRedirect(redirect_url) 
      return f(request, *args, **kwargs) 
     return wraps(f)(wrapper) 
    return decorator 

:あなたの助けを

@object_required(Location, "/") 
def my_view_function(request): 
    # your view code 
+0

ありがとうございます。これをプロジェクト全体での再利用という観点から考えれば、どこに最適な場所でしょうか?デコレータ機能だけの別のアプリは過度のものでしょうか? – Dan

+0

おそらく、 'utils'アプリケーションを作成し、デコレータを' utils.decorators'に入れてください。 – Alasdair

関連する問題