2009-12-15 17 views
6

Estoy luchando con la mejor manera de crear páginas HTML en Django que se pueden usar para mostrar o editar datos. Es decir, me gustaría que los valores del campo aparezcan como texto en el modo de visualización, pero en sus widgets cuando esté en el modo de edición/agregar. Parece que Django no fue diseñado para hacer esto: los campos siempre aparecen en sus widgets (por ejemplo, entrada de texto, área de texto, , etc.).Uso de formularios de Django para mostrar y editar?

¿Existe una técnica común para manejar esto, salvo el uso de formularios para uno, y no para el otro?

Estaba pensando en un filtro templatetag a medida que se podría utilizar para cada campo de formulario, como:

{{form.field_name | render_field: Modo}}

donde render_field sería bien volver HTML del campo widget, o solo el valor como texto, basado en el modo.

¿Me he perdido algo o es una solución viable?

Respuesta

3

Respondiendo a mi propia pregunta, al parecer. Que terminó con una solución de tres partes:

  1. adjuntar el modelo de la forma, así que voy a tener los widgets de la pantalla por defecto para cada campo
  2. Escribe la forma usando una etiqueta de plantilla, pasándole el formulario .field, el usuario y la acción
  3. escribir una etiqueta plantilla de render para manejar # 2

Primer paso:

 
form.model = Model(...) 

Paso dos:

 

{{form.field1.label}} 
{% render form.field1 user action %} 


{{form.field2.label}} 
{% render form.field2 user action %} 

Paso tres:

Algo así como:

 
def render(formfield, user, action, default_text="Private"): 
    if not user.is_authenticated(): 
     action = "view" 
    if action == "view": 
     if user.is_authenticated(): 
      fieldname = formfield.name 
      retval = str(getattr(formfield.form.model, fieldname)) 
     else: 
      retval = default_text 
    else: 
     retval = formfield.as_widget() 
    return retval 
0

Dado que está guardando los datos, debe tener un modelo adjunto al formulario de alguna manera, una forma de modelo o no. De modo que puede usar ese modelo directamente para obtener los valores y presentarlos en una plantilla como desee.

La sugerencia anterior sería posible, pero dado que los formularios pueden ser bastante complejos, probablemente no sea una tarea fácil o que valga la pena. Depende de la frecuencia con la que quieras hacer esto. Pero entonces probablemente sería más fácil crear un filtro para el modelo en lugar de la forma.

+0

Sí, sólo puede utilizar el modelo, pero eso no toma ventaja de todo lo que pueden hacer formas. ¿Qué tendría que ver un filtro con esto? Tengo muchas vistas de visualización/edición, por lo que una buena elección podría evitar que tengamos que hacer cada una dos veces (una para mostrar, una para editar). –

0

en una plantilla principal hacer

{% if form %} 
    {% include 'form.html' %} 
{% else %} 
    {% include 'display.html' %} 
{% endif %} 

entonces esas dos plantillas sería sólo la parte que hace que una forma, o un buen div organizada. de esta manera, la vista de edición tendría una forma definida, y la vista de visualización no. será mucho más fácil hacer un seguimiento de lo que estás tratando de hacer (aunque lo que intentas sea posible, creo que tu método sufrirá en rendimiento).

hago esto en una aplicación de blog para que la página de edición se vea como la página de visualización, por lo que es extremadamente intuitivo para editar/escribir entradas de blog. (Por no hablar de esto me permite poner muy fácilmente algunas ajax para editar entradas en cualquier vista con algunos bonitos efectos de fantasía)

+0

Esto es exactamente lo que no quiero hacer. No quiero tener dos formas, sino una. –

0

¿Me he perdido algo

Formas no sólo mostrar los widgets de campo, pero también maneja los datos de la publicación. Una publicación enviada haría que procesara la limpieza de datos, el formulario y el manejo de errores de campo, etc.

Es como romper el patrón: ¿por qué crear y renderizar un objeto de formulario solo para modificarlo y no parecer una forma?

Si le preocupa demasiado trabajo en plantillas, intente resolverlo con la herencia de plantilla de la mejor manera posible. Si no está muy seguro que desea cambiar sólo la etiqueta del campo, puede hacer algo como

{% if form %} 
    {% for error in form.field.errors %} 
     {{ error|escape }} 
    {% endfor %} 
    {{ form.field }} 
{% else %} 
    {{ object.field }} 
{% endif %} 

para cada campo, pero En mi opinión eso no es el punto, tu caso es distinto.

También lo que viene a la mente (pensando en su solución) es adjuntar widgets dinámicamente para formar campos, pero eso sería una sobreingeniería.

0

Tengo el mismo problema. Ahora mismo tengo plantillas separadas para mostrar y editar; el primero representa campos de objeto, el último forma campos (pero a veces también campos de objeto, para cosas que no son editables). La estructura HTML puede ser bastante compleja: por ejemplo, en algunas páginas tengo tablas grandes que representan una jerarquía de objetos de varios niveles. Como resultado, termino con una gran cantidad de código duplicado en las dos plantillas, que es lo opuesto a DRY.

He utilizado filtros de plantilla con campos de formulario antes, para guardar el código al mostrar los errores junto con el campo. Creo que sería una solución viable en este caso. Otra posibilidad puede ser utilizar una subclase ModelForm a la que se le puede indicar que genere versiones no editables de los campos. Esto ayudaría a mantener las plantillas simples. Incluso podría representar tanto la versión estática como la editable de un campo, y usar JavaScript para alternar entre ellos, activando y desactivando un modo de edición.

Cuestiones relacionadas