Actualizar vista luego de elegir un valor en un select (html)

1,973 views
Skip to first unread message

Marcelo Kazalukian

unread,
Jan 13, 2016, 1:31:32 PM1/13/16
to Django-es

Hola a todos.

Sé que es una pregunta sencilla, pero buscando en internet no encontré una respuesta concreta.

Tengo un select de html con códigos de lugares físicos. Al seleccionar un código de un lugar físico quiero ir a la Base de Datos y traer todos los productos que están en dicho depósito y mostrarlos por pantalla. Si selecciono otro código de lugar físico, nuevamente ir a la Base de Datos y traer los productos correspondientes. 

La idea es seleccionar algunos de los productos, otro código de lugar físico (desde un select distinto al anterior) y presionar "Mover". El botón "Mover" cambia de lugar un conjunto de productos de un lugar a otro.

Entiendo que lo mejor es hacerlo con AJAX para no recargar todo la página y solo cargar la tabla de productos pero me gustaría saber como hacerlo sin AJAX (o sea recargando toda la página) y luego con AJAX.

Muchas gracias a todo.

Francisco R. Del Roio

unread,
Jan 14, 2016, 6:43:08 AM1/14/16
to djan...@googlegroups.com
Hola,
Bueno, sea cual sea el modo, tenés que usar javascript para interseptar
el evento correspondiente al cambio de valor de tu select, y cuando
ocurra enviar el formulario al servidor. En el caso de que se trate de
ajax, simplemente tenés que escribir otra vista con su correspondiente
plantilla, pero en lugar de enviar html o xml, lo ideal sería una salida
JSON.

En caso de que no tengas idea de AJAX, acá tenés un muy buen tutorial
(en inglés): http://www.w3schools.com/ajax/ajax_intro.asp

Podés hacer algo como esto, cada vez que encontras un cambio de valor en
tu SELET:

function cambioLugar() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
var valores = eval("("xhttp.responseText+")")();
}
};

Cuando tengas el objeto JSon podés procesarlo como si fuera un objeto
javascript, iterando por sus matrices, obteniendo valores de sus
propiedades, incluso invocando sus funciones (no recomendado), todo
tenés que hacerlo dentro de la función anónima.

Por ejemplo:

// Primero limpias la lista que querés rellenar
// y después añadís los elementos.
for (i = 0; i<valores.productos.count; i++) {
procesar valores.productos[i];
}

Por cierto, lo último no se si está bien, porque ya tengo una mezcla de
conocimientos de todo un poco y no lo tengo todo ordenado
apropiadamente, pero si sabes javascript sabrás como adaptarlo.

En el caso de que quieras hacerlo recargando la página, podés hacerlo
cambiando la solicitud GET de los parámetros de la solicitud GET, tan
simple como eso.

Un saludo, espero te ayude.
--
¡Cuando tus fuerzas terminan, las de Dios comienzan!

Marcelo Kazalukian

unread,
Jan 14, 2016, 7:15:20 AM1/14/16
to Django-es
Hola Francisco.

Muchas gracias por la respuesta. Me ayudo mucho ya que era una de las dudas que tenía pero me queda la parte de Django sin entenderla completamente.

Para la parte de AJAX voy a usar Jquery. Cuando utilizo el metodo .AJAX de JQuery me pide una URL. Mi duda es a que URL tengo que hacer el pedido? es la misma URL de la vista en la que estoy?

La verdad no logro ver como actualizar el HTML solo en la parte de los productos.

Muchas gracias.

Matias Rs

unread,
Jan 14, 2016, 9:57:44 AM1/14/16
to djan...@googlegroups.com
Hola;

Deberias vos crear una vista con su url, que responda un JSON (si es que prefieres usar JSON) Algo como esto:


from django.http.response import JsonResponse

def productos_por_lugar_list(request, **kwargs):
    if kwargs.get('lugar_id'):
            productos = Product.objects.filter(lugar=kwargs['lugar_id'])
    else:
        productos = []

    return JsonResponse(json.dumps(productos), safe=False)

--
--
Ha recibido este mensaje porque está suscrito a Grupo "Grupo de Usuarios del Framework Django de habla hispana" de Grupos de Google.
Si quieres publicar en este grupo, envía un mensaje de correo
electrónico a djan...@googlegroups.com
Para anular la suscripción a este grupo, envíe un mensaje a django-es-...@googlegroups.com
Para obtener más opciones, visita este grupo en http://groups.google.com.bo/group/django-es.
---
Has recibido este mensaje porque estás suscrito al grupo "Django-es" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a django-es+...@googlegroups.com.
Para acceder a más opciones, visita https://groups.google.com/d/optout.

Marcelo Kazalukian

unread,
Jan 14, 2016, 1:49:40 PM1/14/16
to Django-es
Francisco / mjr muchas gracias a ambos.

Hice un ejemplo sencillo y me funcionó. Les muestro el ejemplo y al final les hago otra consulta:

urls.py

urlpatterns = [
  url
(r'^$', views.prueba, name='prueba'),
  url
(r'^ajax/$', views.ajax, name='ajax'),
]


views.py

def prueba(request):
  return render(request, 'gestion/prueba.html',{})

def ajax(request):
   return HttpResponse("Hola")


prueba.html

{% load static %}
{% block base %}
 <script type="text/ecmascript" src="{% static 'js/jquery-1.11.0.min.js' %}"></script>
 <script type="text/javascript" src="{% static 'js/prueba.js' %}"></script>
    </head>
   <body>
        <p id="prueba"></p>
        <button id="btnAceptar" type="button" >Aceptar</button>
           
{% endblock %}


Prueba.js

$( document ).ready(function() {
 
 $('#btnAceptar').click(function() {
     $.ajax({   
   url: '/ajax/',
      success: function(data) {
         $('#prueba').html(data);
      },   
    });
 });
});

La pagina tiene un botón que al presionarlo escribe dentro de la etiqueta <p> la palabra Hola.

La consulta es la siguiente: cada vez que tenga que retornar algo (lista de productos, el estado de un producto, etc) tengo que crear una vista? es común que en django queden una vista por pantalla y una vista por cada funcionalidad de este tipo? es común un archivo views.py muy grande?

Muchas gracias.

Francisco R. Del Roio

unread,
Jan 14, 2016, 3:05:52 PM1/14/16
to djan...@googlegroups.com
Hola,

El 14/01/2016 a las 03:49 p.m., Marcelo Kazalukian escribió:
> Francisco / mjr muchas gracias a ambos.
>
> Hice un ejemplo sencillo y me funcionó. Les muestro el ejemplo y al
> final les hago otra consulta:
>
> urls.py
>
> |
> urlpatterns =[
> url(r'^$',views.prueba,name='prueba'),
> url(r'^ajax/$',views.ajax,name='ajax'),
No es necesario en realidad, porque bien sabés que una respuesta json
puede tener todos los datos que vos quieras. Podés hacer dos vistas:

* lista_productos: en esta lista podés devolver una lista de productos
basandote en criterios predefinidos construir un queryset con los
parámetros que conseguís de la petición GET/POST a la vista. Por
ejemplo, podés hacer que tu vista filtre por un determinado almacén, o
por un determinado proveedor, etc. En este caso, solo tenés que devolver
información mínima, como por ejemplo los IDs, título, descripción y ruta
al icono/imagen.
* detalle_producto: En esta vista entregás todos los detalles posibles
de un producto, como la localización, proveedor, existencias, en fin, lo
que quieras.

La organización anterior te posibilitaría escribir un buscador usando
ajax y que no sobrecargue el navegador, a la vez que te hace mas
flexible el programa.

Otra cosa, para devolver información sobre objetos relacionados, no es
necesario que entregues toda la información sobre ellos. Lo justo y
necesario es suficiente, por ejemplo los IDs del almacén, del proveedor,
etc.

Un consejo: mirate las lecciones de la documentación sobre las vistas
basadas en clases. Te ahorraría muchísimo trabajo conocerlas.

Espero te ayude.

Marcelo Kazalukian

unread,
Jan 15, 2016, 8:32:51 AM1/15/16
to Django-es
Francisco, nuevamente muchas gracias.

Lo que entendí es que podría crear una vista "query_productos" y según los parámetros que le envío a la vista genero un JSON u otro distinto. De la misma forma puedo crear las vistas "query_stock", "query_clientes", etc con distintos JSON como respuesta según los criterios elegidos en pantalla por el usuario. 

Empiezo a leer sobre vistas basadas en clases (estas son las cosas que hay que saber para no quedarse con malas prácticas).

Muchas gracias.
Reply all
Reply to author
Forward
0 new messages