個人的には、Djangoに固有ではないPython機能であるデコレータの大ファンです。デコレータは、高階関数に加えて完璧なシンタックスシュガーであり、ビューのボイラープレートを減らすのに特に役立ちます。一般化されたラッパー関数をすばやく定義できます。この関数では、繰り返しコードを配置して、簡単に再利用でき、便利なものにすることができます。 -リファクタリングを停止します。
それらがどのように機能するかを説明するよりも、おそらくあなたに見せることの方が簡単です。簡略化したビューの例を次に示します。
def listpage(request):
return HttpResponse(render_to_string("itemlist.html", {
"items": Item.objects.filter(visible=True).order_by("-modifydate")
}))
def itemlist_tags(request, tags):
return HttpResponse(render_to_string("itemlist.html", {
"items": Item.objects.tagged(name=tags).filter(visible=True).order_by("-modifydate"),
}))
...しかし、これらのページでユーザーがログインする必要があるようにしたいとします。次のようにログインコードを追加できます。
def listpage(request):
if not request.user.is_authenticated():
return f(request, *args, **kwargs)
else:
return HttpResponse(render_to_string("itemlist.html", {
"items": Item.objects.filter(visible=True).order_by("-modifydate")
}))
def itemlist_tags(request, tags):
if not request.user.is_authenticated():
return f(request, *args, **kwargs)
else:
return HttpResponse(render_to_string("itemlist.html", {
"items": Item.objects.tagged(name=tags).filter(visible=True).order_by("-modifydate"),
}))
...これは、不自然な例であっても、著しく大きく、反復的になり始めています。次のように、デコレータを使用して関数を再びスリムにすることができます。
デコレータからインポートデコレータ
@decorator
def loginrequired(f, request, *args, **kwargs):
if request.user.is_authenticated():
return f(request, *args, **kwargs)
else:
return HttpResponseRedirect("/")
@loginrequired
def listpage(request):
return HttpResponse(render_to_string("itemlist.html", {
"items": Item.objects.filter(visible=True).order_by("-modifydate")
}))
@loginrequired
def itemlist_tags(request, tags):
return HttpResponse(render_to_string("itemlist.html", {
"items": Item.objects.tagged(name=tags).filter(visible=True).order_by("-modifydate"),
}))
@loginrequired
def another_such_function(request):
(...)
@loginrequired
def and_again(request):
(...)
デコレータ関数は、関数の定義時に実行されます。私の例の「f」は、デコレータが適用される関数を表すオブジェクトであり、無限の方法で操作できます。
これにはデコレータライブラリが必要です。これは、多くの優れたpython morselsと同様に、PyPIでは無料です。
デコレータ関数を作成するためにこのライブラリは必要ありませんが、特に最初は便利です。彼らはもっとたくさんのことをすることができます-どんな呼び出し可能なものもデコレータになることができます。クラスメソッドを装飾し、self
変数をインターセプトできます。デコレータは、次のようにチェーン化できます。
@second
@first
def originalfunction(*args):
(...)
この概念があなたの食欲を刺激した場合、私はあなたがそのような簡単な高階関数の操作で何ができるかについての探求をあなたに任せます。あなたや他の好奇心旺盛な新しいPython愛好家のために、さらに多くの例があります。幸運を。