2012-05-15 18 views
26

Digamos que tenemos una página de Django que muestra una lista de elementos y permite al usuario completar un formulario para agregar a los artículos (llamemos a las publicaciones).Django - dos vistas, una página

Lo que quiero: La URL de esta página hace referencia a una vista. La vista llama a otras dos vistas (llamadas "sub-view" aquí), luego cada sub-vista representa su sección y devuelve los resultados. La vista principal luego se une a los resultados de las sub-vistas y lo devuelve.

Idealmente, tendría una javascript javascript rápida en la página - si javascript está habilitado, el botón de enviar para el formulario será "Ajax" a la sub-vista que trata de agregar el formulario, y la página ser actualizado de esa manera. Supongo que podría activar una solicitud para actualizar la lista de publicaciones también o algo así.

Entonces, ¿cómo puedo concatenar las dos sub-vistas en la vista principal? es posible?

ACTUALIZACIÓN: "subvista" es un término que inventé. Lo que quiero es una vista que pueda ser llamada directamente por Ajax para devolver algo significativo, o desde otra vista (que llamaré la "vista principal"). Si es llamado por esta "vista principal", ¿cómo maneja la vista principal al retornar los datos desde múltiples "sub-vistas"?

¿Hay una manera simple de hacer esto? ¿Es esto una manera apropiada de pensar en vistas múltiples en una página? ¿Debería preocuparme por la separación de responsabilidades?

+0

sub-views son su propio término. depende de lo que devuelvan html? ¿datos? – jdi

Respuesta

15

Una vista en django es cualquier llamante que finalmente devuelve un objeto Response. Dentro de ese punto de vista, podría dividir el trabajo en la organización que más le convenga. Tal vez su punto de vista 100% delegue a otros métodos.

En su caso, su vista principal llamaría a otras 2 funciones para datos. También podrían ser vistas si también aceptan un objeto Request y lo usan. También tendrían que devolver objetos de respuesta para que se los considere vistas de django, ya que así es como apuntarías las URL hacia ellos. Pero en realidad no te sirve de nada tener otras dos vistas que te devuelvan tus objetos de Respuesta. Lo que probablemente desee es solo otros métodos que realicen tareas específicas y devuelvan alguna estructura de datos, o tal vez incluso un fragmento procesado de una plantilla. Luego usaría estos datos, o combinaría las cadenas de plantillas juntas y las devolvería en su Respuesta principal.

Si realmente está configurado en hacer uso de otros puntos de vista que devuelven los objetos de respuesta, entonces usted puede hacer algo como agarrar el cuerpo fuera de ellos, y su fusión en su propia respuesta:
https://docs.djangoproject.com/en/1.4/ref/request-response/

Realmente, nada es muy diferente de los tutoriales. Simplemente llama a otros métodos para obtener datos. Si desea organizarlo, debe separar la lógica de procesamiento de datos de la función de vista. Su vista principal llamaría a estas funciones de procesamiento de datos para los valores. Y sus "vistas secundarias" serían simples vistas que también llaman a estas funciones de datos individuales y las envuelven en una Respuesta.

Pseudo:

def mainView(request): 
    val = data1() 
    val2 = data2() 
    response = # val + va2 + other stuff 
    return response 

def subView1(request): 
    val = data1() 
    response = # val + stuff 
    return response 

def subView2(request): 
    val2 = data2() 
    response = # val2 + stuff 
    return response 

def data1(): 
    val = # get data 
    return val 

def data2(): 
    val2 = # get data 
    return val2 
+0

Correcto, entonces no puedo devolver una respuesta para fusionarla con otra ... S lo que necesitaría, entonces, son 3 métodos de vista y dos métodos de trabajo. El trabajo de las llamadas "sub visiones" se haría en los métodos de trabajo-caballo. Obteniendo datos, etc., guardando, lo que sea. Dos de las vistas simplemente delegarían a cualquiera de los caballos de trabajo, y luego devolverían esos datos como respuesta. La otra vista: la "vista principal" llamaría a ambos caballos de trabajo y lo devolvería como respuesta. ¿Derecha? – bharal

+0

@bharal: Exactamente. Y vea la actualización que acabo de hacer mostrando eso. Puede hacer que sus puntos de vista sean muy claros y solo para formatear datos. Luego, ponga su lógica en una función más común para que la use todo según sea necesario. – jdi

+0

Hola, jdi: me gusta esta respuesta, pero completa, ¿la respuesta proporcionada por Yuji es diferente? ¿Lo mismo? Una forma diferente de resolver el problema? – bharal

12

Las vistas deben contener únicamente relacionados con vistas lógica:

  • Las vistas son de procesar las solicitudes y servir los datos solicitados
  • Eso incluye la revisión de la autorización de usuario/autorización y tratar con los parámetros dados
  • Si los datos requeridos no son triviales, subcontrate el código a una ubicación más apropiada (el modelo o definiciones de formulario o en otro lugar del cliente)

cálculos Externalizar para que sean reutilizables y llamar a estos métodos desde su punto de vista a mantenerlos pequeños.

Sin embargo, tal vez desee algo más, es decir, plantillas con extends y include.

Con extends puede crear un diseño base para su código HTML y definir bloques específicos que se pueden representar en otro lugar. ¿Ejemplo? De acuerdo.

base.html:

<!doctype html> 
<html> 
    <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
     <title>{% block title %}My Site{% endblock %}</title> 
    </head> 
    <body> 
     <div id="header"> 
      <h1>My Site</h1> 
     </div> 
     {% block content %}{% endblock %} 
    </body> 
</html> 

Entonces, en cualquier otra plantilla, puede sobrescribir los bloques title y content la que hemos definido en la plantilla base:

{% extends "base.html" %} 

{% block title %}My Page{% endblock %} 

{% block content %} 
<h2>My Page</h2> 
<div>lorem ipsum</div> 
{% endblock %} 

Además, puede crear sub-plantillas como la siguiente, llamémoslo _item.html:

<li class="item"> 
    <span>{{ something.foo }}</span> 
    <strong>{{ something.bar }}</span> 
</li> 

puede incluir esa fragmento en cualquier otra plantilla y pasar un número arbitrario de parámetros:

{% for something in mymodel.mym2mrelation.all %} 
    {% include "_item.html" with something=something only %} 
{% endfor %} 

Naturalmente, se pueden combinar ambos conceptos. De la misma manera:

{% extends "base.html" %} 

{% block title %}My Page{% endblock %} 

{% block content %} 
<h2>My Page</h2> 
<div>lorem ipsum</div> 
<ul> 
{% for something in mymodel.mym2mrelation.all %} 
    {% include "_item.html" with something=something only %} 
{% endfor %} 
</ul> 
{% endblock %} 

Espero que ayude.

+0

Las vistas deben contener toda la lógica específica de la vista ... La mayoría del código de vista depende del objeto de solicitud, que en la mayoría de los casos no se debe incluir en un modelo. Tu publicación puede ser confusa para los nuevos usuarios ... –

+0

tienes razón, voy a reformular que – Alp

8

Este es el momento perfecto para introducir class based views.

métodos de clase son esencialmente "sub vistas" que dividen la lógica en fragmentos reutilizables.

Si desea la legibilidad de las funciones divididas, solo mejora usando las vistas basadas en clases de django (a través de todas las funcionalidades proporcionadas por defecto y acceso a solicitudes, kwargs, args, etc., a través de la instancia de clase).

The docs incluso contienen un buen ejemplo para devolver una respuesta JSON o respuesta HTML basada en los parámetros de solicitud (esta situación exacta).

¿Cuál es la mejor parte? Puede reutilizar sus vistas basadas en clases como mixins en vistas futuras. Mire el ejemplo de documentos para ver cómo convertir cualquier vista basada en clases para manejar una respuesta JSON del contexto de la plantilla a través de una subclase simple.

+0

¿Es esta la misma respuesta que jdi (filosóficamente, quiero decir), o implica algo diferente? – bharal

Cuestiones relacionadas