2016 年の更新された回答:最新の Django には、必要なすべてが組み込まれており、クラスベースのビューを通じて利用できます。最も生の形式では、正規のアプローチはdjango.views.generic.View
、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 はクラスベースのビューを取得し、現在では標準的な方法になっています。私はこれを単に歴史的な目的のためにここに置いています。古い回答テキストは次のとおりです。
異なる HTTP メソッド (これは私の小さな WebDAV 実装です) に対して個別のコードが必要な 1 つの特定のビューでは、次のようなことをしています:
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()),
追加/編集:まあ、少し考えて、実際にデコレータのアプローチを実装しました。私が最初に思ったほど悪くはありません。
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'),
とにかく、この投稿はコミュニティ ウィキなので、アイデアが気に入ったら自由に改善してください。また、改訂履歴には、これを書く前に試した少し異なるアプローチも含まれています...