سؤال

في ASP.NET MVC، يمكنك استخدام سمة AcceptVerbs لربط دالة عرض بفعل:

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

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

كتاب جانجو يقترح شيئا مثل هذا:

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

URL.py:

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

يبدو هذا قبيحًا بعض الشيء بالنسبة لي - هل هناك مصمم ديكور يمكنه ربط فعل HTTP بطريقة عرض، أو نمط ASP.NET MVC، أو طريقة أخرى مقبولة للقيام بذلك؟

هل كانت مفيدة؟

المحلول

وهناك معيار المدمج في الديكور لطلب معين طريقة HTTP أو قائمة الأساليب المسموح بها.

وراجع التعليمات البرمجية: HTTP: // التعليمات البرمجية. djangoproject.com/browser/django/trunk/django/views/decorators/http.py.

نصائح أخرى

الإجابة المحدثة في عام 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، ولكنه ليس حلاً جافًا، لذا لا تستخدمه.في عام 2011، حصل Django على طرق عرض قائمة على الفصل، وهي في الوقت الحاضر هي الطريقة القياسية لكيفية القيام بالأشياء.أنا أحتفظ بهذا هنا فقط للأغراض التاريخية.نص الإجابة القديم يلي:

في عرض واحد محدد حيث أحتاج إلى رمز منفصل لطرق HTTP المختلفة (هذا هو تطبيق WebDAV الصغير الخاص بي)، أفعل شيئًا مثل هذا:

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

على أية حال، هذا المنشور عبارة عن موقع ويكي مجتمعي، لذا لا تتردد في تحسينه إذا أعجبتك الفكرة!ويحتوي سجل المراجعة أيضًا على بعض الأساليب المختلفة التي جربتها قبل كتابة هذا ...

ويمكنك استخدام مشاهدة ديكور

ومن المستندات:

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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top