5

ASP.NET MVC では、AcceptVerbs 属性を使用して、ビュー関数を動詞に関連付けることができます。

public ActionResult Create()
{
    // do get stuff
} 

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(FormCollection collection)
{
    // do post stuff
}

Django Bookは、次のようなことを提案しています。

def method_splitter(request, *args, **kwargs):
    get_view = kwargs.pop('GET', None)
    post_view = kwargs.pop('POST', None)
    if request.method == 'GET' and get_view is not None:
        return get_view(request, *args, **kwargs)
    elif request.method == 'POST' and post_view is not None:
        return post_view(request, *args, **kwargs)
    raise Http404

urls.py:

urlpatterns = patterns('',
    # ...
    (r'^somepage/$', views.method_splitter, {'GET': views.some_page_get, 
        'POST': views.some_page_post}),
    # ...
)

それは私には少し醜いようです.HTTP動詞をビュー、ASP.NET MVCスタイル、またはこれを行うための別の受け入れられた方法に関連付けることができるデコレータはありますか?

4

3 に答える 3

11

特定の HTTP メソッドまたは許可されたメソッドのリストを要求するための標準の組み込みデコレーターがあります。

コードを参照してください: http://code.djangoproject.com/browser/django/trunk/django/views/decorators/http.py

于 2009-06-19T05:53:49.140 に答える
9

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'),

とにかく、この投稿はコミュニティ ウィキなので、アイデアが気に入ったら自由に改善してください。また、改訂履歴には、これを書く前に試した少し異なるアプローチも含まれています...

于 2009-06-18T16:24:03.400 に答える
3

ビューデコレータを使用できます

ドキュメントから:

from django.views.decorators.http import require_http_methods

@require_http_methods(["GET", "POST"])
def my_view(request):
    # I can assume now that only GET or POST requests make it this far
    # ...
    pass
于 2012-03-01T21:53:09.313 に答える