respuesta actualizada en 2016: moderna Django tiene todo lo necesario built-in y disponible a través del class-based views. En la forma más cruda, el enfoque canónico es subclasssing django.views.generic.View
y la aplicación de métodos de clase que llevan el nombre de los verbos HTTP:
class MyView(View):
def get(self, request, *args, **kwargs):
# ...
def post(self, request, *args, **kwargs):
# ...
Internamente, esto funciona de una manera muy similar a mi antiguo código de abajo (que fue escrito antes Django tenía vistas basadas en clases). Hay un método View.dispatch
que básicamente busca qué llamar, o devuelve 405 si no puede encontrar nada: getattr(self, request.method.lower(), self.http_method_not_allowed)
.
Por supuesto, si realiza el procesamiento, la representación de la plantilla o las cosas comunes de CRUD, asegúrese de consultar las subclases View
disponibles.
Legacy answer from 2009 a continuación. El código aún funciona en 2016, pero no es una solución SECA, así que no lo use. En 2011 Django obtuvo vistas basadas en clases y hoy en día son la forma estándar de cómo se deben hacer las cosas. Lo mantengo aquí solo con fines históricos. texto de la respuesta de edad sigue:
En una visión particular en el que deben tener el código separado para diferentes métodos HTTP (esta es mi pequeña aplicación WebDAV), que estoy haciendo algo como esto:
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()),
Agregado/editado: Bueno, he pensado un poco y realmente implementé el enfoque de decorador. No es tan malo como inicialmente pensé.
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'),
Este post es una wiki de la comunidad, de todos modos, así que no dude que mejorar si te gusta la idea! Y el historial de revisión también contiene algunas aproximaciones un poco diferentes que probé antes de escribir esto ...
Esta es de hecho la manera de hacerlo. Tenga en cuenta que también hay un generador de decorador que le permite crear decoradores para cualquier combinación de métodos que desee. (y no tengo idea de por qué se votó negativamente por dar la respuesta obvia y correcta a la pregunta ...) –
Creo que esta no es la respuesta correcta, porque require_http_methods() es un filtro, no un despachador. No se puede hacer @require_http_methods ("GET") para una función, @require_http_methods ("POST") para otra (¡con el mismo nombre!), Y dejar que Django elija la adecuada para llamar por método de verbo. – drdaeman