最新の2016年の回答:現代のDjangoには、必要なものがすべて組み込まれており、class-based viewsから入手できます。ほとんどの生の形式では、標準的なアプローチはdjango.views.generic.View
をsubclasssingとHTTP動詞にちなんで命名されたクラスのメソッド実装されています。内部
class MyView(View):
def get(self, request, *args, **kwargs):
# ...
def post(self, request, *args, **kwargs):
# ...
を、これは以前に書かれていた(以下の私の古代のコードと非常によく似た方法で動作しますDjangoにはクラスベースのビューがありました)。基本的に何を呼び出すかを調べるView.dispatch
メソッドがあります。何も見つからない場合は405を返します。getattr(self, request.method.lower(), self.http_method_not_allowed)
。
もちろん、フォーム処理、テンプレートレンダリング、一般的なCRUDなどを行う場合は、利用可能なView
サブクラスを確認してください。
以下の2009年のレガシー回答。コードはまだ2016年に動作しますが、DRYソリューションではありませんので、使用しないでください。 2011年にDjangoはクラスベースのビューを取得しましたが、現在では、これらのメソッドを標準的な方法で実行する必要があります。私は歴史的な目的のためだけにこれを保管しています。旧解答テキストは、次のとおりです。
class SomeView(object):
def method_get(self, request, ...):
...
def __call__(self, request, *args, **kwargs):
m = getattr(self, 'method_%s' % request.method.lower(), None)
if m is not None:
return m(request, user, *args, **kwargs)
return HttpResponseNotAllowed("405 Method Not Allowed")
# Then url(r'...', SomeView()),
を追加しました:
を私は別のHTTPメソッド用に別のコードを持っている必要がある1つの特定のビューでは(これは私の小さなWebDAV実装である)、私はこのような何かをやっています/編集:まあ、私は少し考えて、実際にデコレータのアプローチを実装しました。私が最初に思ったほど悪くはありません。
def method_not_allowed_view(request, *args, **kwargs):
return HttpResponseNotAllowed("405 Method Not Allowed")
def http_method(*methods):
methods = map(lambda m: m.lower(), methods)
def __method_wrapper(f):
this_module = __import__(__name__)
chain = getattr(this_module, f.__name__, method_not_allowed_view)
base_view_func = lambda request, *args, **kwargs: \
f(request, *args, **kwargs) if request.method.lower() in methods \
else chain(request, *args, **kwargs)
setattr(this_module, f.__name__, base_view_func)
return base_view_func
return __method_wrapper
@http_method('get')
def my_view(request):
return HttpResponse("Thank you for GETting.")
@http_method('post', 'put')
def my_view(request):
return HttpResponse("Thank you for POSTing or PUTting.")
# url(r'...', 'app.my_view'),
この投稿は、とにかくコミュニティのwikiですので、気に入ったら改善してください!また、改訂履歴には、これを書く前に試してみた少し異なるアプローチが含まれています...
これは本当にそれを行う方法です。そこにはデコレータジェネレータもありますので、好きなメソッドの組み合わせに合わせてデコレータを作成することができます。 (なぜ私はあなたが質問に明白で正しい答えを与えるためにdownvotedを得たのかわかりません) –
require_http_methods()はフィルタでありディスパッチャではないので、これは正解ではないと私は信じています。ある関数の@require_http_methods( "GET")、別のもの(@同じ名前の!)の@require_http_methods( "POST")を実行することはできず、Djangoはメソッド動詞で呼び出す適切なものを選択させます。 – drdaeman