python - template - formularios avanzados django
Vistas de clase en Django (9)
A menos que desee hacer algo un poco complejo, utilizar las vistas genéricas es el camino a seguir. Son mucho más potentes de lo que su nombre lo indica, y si solo está mostrando datos de modelo, las vistas genéricas harán el trabajo.
Django view apunta a una función, que puede ser un problema si desea cambiar solo un poco de funcionalidad. Sí, podría tener millones de argumentos de palabras clave e incluso más si las declaraciones en la función, pero estaba pensando más en un enfoque orientado a objetos.
Por ejemplo, tengo una página que muestra un usuario. Esta página es muy similar a la página que muestra un grupo, pero aún no es tan similar a usar otro modelo de datos. El grupo también tiene miembros, etc.
Una forma sería apuntar vistas a métodos de clase y luego extender esa clase. ¿Alguien ha intentado este enfoque o tiene alguna otra idea?
He creado y usado mis propias clases de vista genéricas, definiendo
__call__
para que una instancia de la clase sea invocable.
Me gusta mucho;
mientras que las vistas genéricas de Django permiten cierta personalización a través de argumentos de palabras clave, las vistas genéricas de OO (si su comportamiento se divide en varios métodos separados) pueden tener una personalización mucho más detallada a través de la subclasificación, lo que me permite repetirme mucho menos.
(Me canso de reescribir la misma lógica de vista de creación / actualización cada vez que necesito modificar algo que las vistas genéricas de Django no permiten).
He publicado un código en djangosnippets.org .
El único inconveniente real que veo es la proliferación de llamadas a métodos internos, que pueden afectar el rendimiento de alguna manera. No creo que esto sea una gran preocupación; Es raro que la ejecución del código de Python sea su cuello de botella de rendimiento en una aplicación web.
ACTUALIZACIÓN : las propias vistas genéricas de Django ahora están basadas en clases.
ACTUALIZACIÓN : FWIW, he cambiado mi opinión sobre las opiniones basadas en la clase desde que se escribió esta respuesta. Después de haberlos usado extensamente en un par de proyectos, siento que tienden a generar código que es satisfactoriamente SECO para escribir, pero muy difícil de leer y mantener más tarde, porque la funcionalidad se extiende por tantos lugares diferentes y las subclases son muy dependientes en cada detalle de implementación de las superclases y mixins. Ahora siento que TemplateResponse y los decoradores de vistas son una mejor respuesta para descomponer el código de vista.
Las vistas genéricas generalmente serán el camino a seguir, pero en última instancia, usted es libre de manejar las URL como lo desee. FormWizard hace las cosas de una manera basada en clases, al igual que algunas aplicaciones para API RESTful.
Básicamente, con una URL, se le dan un montón de variables y un lugar para proporcionar un llamado, lo que usted proporciona depende completamente de usted, la forma estándar es proporcionar una función, pero en última instancia, Django no impone restricciones a lo que hace.
Estoy de acuerdo en que algunos ejemplos más de cómo hacerlo serían buenos, aunque FormWizard es probablemente el lugar para comenzar.
Me parece que estás tratando de combinar cosas que no deberían combinarse. Si necesita hacer un procesamiento diferente en su vista dependiendo de si es un objeto de Usuario o Grupo que está tratando de ver, entonces debe usar dos funciones de vista diferentes.
Por otro lado, puede haber expresiones idiomáticas comunes que desee extraer de sus vistas de tipo object_detail ... ¿tal vez podría usar un decorador o simplemente funciones auxiliares?
-Dan
Necesitaba usar vistas basadas en clases, pero quería poder usar el nombre completo de la clase en mi URLconf sin tener que crear instancias de la clase de vista antes de usarla. 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)
Ahora puedo crear instancias de clases de vista y usar las instancias como funciones de vista, O simplemente puedo apuntar mi URLconf a mi clase y hacer que la metaclase instancia (y llame) la clase de vista por mí.
Esto funciona comprobando el primer argumento de
__call__
: si se trata de una solicitud
HttpRequest
, debe ser una solicitud HTTP real porque sería absurdo intentar instanciar una clase de vista con una instancia
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''),
)
(Publiqué un fragmento para esto en http://djangosnippets.org/snippets/2041/ )
Puede usar las Vistas genéricas de Django. Puede lograr fácilmente la funcionalidad deseada a través de Vistas genéricas de Django
Si desea compartir una funcionalidad común entre páginas, le sugiero que busque etiquetas personalizadas. Son bastante fáciles de crear y son muy potentes.
Además, las plantillas pueden extenderse desde otras plantillas . Esto le permite tener una plantilla base para configurar el diseño de la página y compartirla entre otras plantillas que completan los espacios en blanco. Puede anidar plantillas a cualquier profundidad; lo que le permite especificar el diseño en grupos separados de páginas relacionadas en un solo lugar.
Si simplemente está mostrando datos de modelos, ¿por qué no usar las Vistas genéricas de Django ? Están diseñados para que pueda mostrar fácilmente los datos de un modelo sin tener que escribir su propia vista y cosas sobre el mapeo de los parámetros de URL a las vistas, la obtención de datos, el manejo de casos extremos, la salida de representación, etc.
Siempre puede crear una clase, anular la función
__call__
y luego apuntar el archivo URL a una instancia de la clase.
Puede echar un vistazo a la clase
FormWizard
para ver cómo se hace esto.