que necesitaba usar puntos de vista basados en la clase, pero quería ser capaz de utilizar el nombre completo de la clase en mi URLconf sin tener siempre que una instancia de la clase de vista antes de usarlo. Lo que me ayudó fue una metaclase sorprendentemente simple:
class CallableViewClass(type):
def __call__(cls, *args, **kwargs):
if args and isinstance(args[0], HttpRequest):
instance = super(CallableViewClass, cls).__call__()
return instance.__call__(*args, **kwargs)
else:
instance = super(CallableViewClass, cls).__call__(*args, **kwargs)
return instance
class View(object):
__metaclass__ = CallableViewClass
def __call__(self, request, *args, **kwargs):
if hasattr(self, request.method):
handler = getattr(self, request.method)
if hasattr(handler, '__call__'):
return handler(request, *args, **kwargs)
return HttpResponseBadRequest('Method Not Allowed', status=405)
puedo ahora ambos instanciar clases de vista y el uso de los casos como funciones de vista, o simplemente puedo señalar mi URLconf a mi clase y tienen la instantiate metaclase (y llamada) la clase de vista para mí. Esto funciona verificando el primer argumento en __call__
- si es un HttpRequest
, debe ser una solicitud HTTP real, ya que no tendría sentido recurrir a una instancia de una clase de vista con una instancia de HttpRequest
.
class MyView(View):
def __init__(self, arg=None):
self.arg = arg
def GET(request):
return HttpResponse(self.arg or 'no args provided')
@login_required
class MyOtherView(View):
def POST(request):
pass
# And all the following work as expected.
urlpatterns = patterns(''
url(r'^myview1$', 'myapp.views.MyView', name='myview1'),
url(r'^myview2$', myapp.views.MyView, name='myview2'),
url(r'^myview3$', myapp.views.MyView('foobar'), name='myview3'),
url(r'^myotherview$', 'myapp.views.MyOtherView', name='otherview'),
)
(he publicado un fragmento de este a http://djangosnippets.org/snippets/2041/)
La ejecución de Python no es EL cuello de botella, pero podría afectar la escalabilidad del sitio y, en general, el rendimiento. ¡Estoy tan contento de que exista Memcache! – StefanNch