Question

Dans ASP.NET MVC, vous pouvez utiliser l'attribut AcceptVerbs pour corréler une fonction d'affichage avec un verbe:

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

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

Le livre Django suggère quelque chose comme ceci:

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/

Cela me semble un peu moche - existe-t-il un décorateur pouvant associer un verbe HTTP à une vue, style ASP.NET MVC, ou un autre moyen accepté de le faire?

, views.method_splitter, {'GET': views.some_page_get, 'POST': views.some_page_post}), # ... )

Cela me semble un peu moche - existe-t-il un décorateur pouvant associer un verbe HTTP à une vue, style ASP.NET MVC, ou un autre moyen accepté de le faire?

Était-ce utile?

La solution

Il existe des décorateurs intégrés standard qui exigent une méthode HTTP particulière ou une liste de méthodes autorisées.

Voir le code: http: // code. djangoproject.com/browser/django/trunk/django/views/decorators/http.py .

Autres conseils

Réponse mise à jour en 2016: Django moderne a tout intégré et disponible via le vues basées sur les classes . Dans la forme la plus brute, l’approche canonique consiste à sous-classer django.views.generic.View et à mettre en œuvre des méthodes de classe nommées après les verbes HTTP:

class MyView(View):
    def get(self, request, *args, **kwargs):
        # ...

    def post(self, request, *args, **kwargs):
        # ...

En interne, cela fonctionne d’une manière très similaire à mon ancien code ci-dessous (qui était écrit avant que Django n’ait une vue basée sur les classes). Il existe une méthode View.dispatch qui recherche en gros ce qu'il faut appeler ou renvoie 405 si rien ne se trouve: getattr (self, request.method.lower (), self. http_method_not_allowed) .

Bien sûr, si vous effectuez un traitement de formulaire, un rendu de modèle ou des éléments CRUD courants, veillez à vérifier les sous-classes View disponibles.

Réponse héritée de 2009 ci-dessous. Le code fonctionne toujours en 2016, mais n'est pas une solution DRY, ne l'utilisez donc pas. En 2011, Django a obtenu des vues basées sur les classes et, de nos jours, elles constituent le moyen standard de procéder. Je garde cela ici uniquement à des fins historiques. L’ancien texte de réponse suit:

Dans une vue particulière où il me faut un code distinct pour différentes méthodes HTTP (c'est ma minuscule implémentation WebDAV), je fais quelque chose comme ceci:

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

Ajouté / modifié: Eh bien, j'ai réfléchi un peu et mis en place une approche de décorateur. Ce n’est pas aussi grave que je le pensais au départ.

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

Ce billet est un wiki de communauté, alors n'hésitez pas à vous améliorer si vous aimez l'idée! Et l'historique de révision contient également des approches un peu différentes que j'ai essayées avant d'écrire ceci ...

Vous pouvez utiliser Afficher les décorateurs

.

À partir de la documentation:

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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top