2011-01-26 41 views
50

Uno de mi vista necesita agregar un elemento, junto con otra funcionalidad, pero ya tengo otra vista que agrega específicamente un elemento.¿Puedo llamar una vista desde otra vista?

¿Puedo hacer algo como:

def specific_add_item_view(request): 
    item = Item.objects.create(foo=request.bar) 

def big_view(request): 
    # ... 
    specific_add_item_view(request) 
+0

Creo que su uso sea más sencillo: specific_add_item_view retorno (solicitud) Sólo para –

Respuesta

38

Ver funciones deben devolver un rendido HTML de vuelta al navegador (en un HttpResponse). Llamar a una vista dentro de una vista significa que estás (potencialmente) haciendo el renderizado dos veces. En su lugar, simplemente factorice el "agregar" en otra función que no sea una vista, y haga que ambas vistas lo llamen.

def add_stuff(bar): 
    item = Item.objects.create(foo=bar) 
    return item 

def specific_add_item_view(request): 
    item = add_stuff(bar) 
    ... 

def big_view(request): 
    item = add_stuff(bar) 
    ... 
+15

¿Qué hacemos en caso de que la vista llamada esté en una aplicación de un tercero? –

+0

Seth, cómo llamar a la variable de view1 en la plantilla o cómo usar la variable de view1 para mostrar – user2086641

50

Claro, siempre y cuando todo está dicho y hecho su vista devuelve un objeto HttpResponse. El siguiente es completamente válido:

def view1(request): 
    # do some stuff here 
    return HttpResponse("some html here") 

def view2(request): 
    return view1(request) 

Si no desea devolver el HttpResponse desde la primera vista, entonces simplemente almacenar en alguna variable de ignorar:

def view1(request): 
    # do some stuff here 
    return HttpResponse("some html here") 

def view2(request): 
    response = view1(request) 
    # do some stuff here 
    return HttpResponse("some different html here") 
+0

aclare lo que está haciendo: en el segundo ejemplo, solo está lanzando una lógica en la vista 1, no hará nada con los objetos de respuesta, ¿verdad? –

+4

Sí, esa es la idea. 'view1' probablemente opera en un objeto de un modelo o algo. Seth tiene la idea correcta sin embargo. Probablemente sea mejor sacar la funcionalidad común de ambas vistas y ponerla en una función que tanto 'view1' como' view2' llaman y luego devuelven sus respectivos objetos HttpResponse. No es necesario generar un HttpResponse que no se vaya a usar, especialmente si incluye una plantilla que requiere muchas consultas. – brady

+0

@ brady, cómo llamar a la variable de view1 en la plantilla o cómo usar la variable de view1 para mostrar – user2086641

4

Una mejor manera es utilizar el sistema de plantillas. Combinando ideas de @Seth y @brady:

def specific_add_item_view(request, extra_context_stuff=None): 
    Item.objects.create() 
    context_variables = {} # obviously want to populate this 
    if extra_context_stuff: 
     context_variables.update(extra_context_stuff) 
    return render(request, 'app_name/view1_template.html', context_variables) 

def bigger_view(request): 
    extra_context_stuff = {'big_view': True} 
    return specific_add_item_view(request, extra_context_stuff) 

Y su nombre_apl/view1_template.html podría contener un código condicional plantilla

{% if big_view %} 
<p>Extra html for the bigger view</p> 
{% endif %} 
+0

Gracias @Neceros por señalar que las versiones recientes de django desprecian 'render_to_response' a favor de' render'. – hobs

Cuestiones relacionadas