Guia Python: alta, listado, consulta y borrado de datos (2a parte).

Publicado el 31 agosto 2013 por Hugo Rep @HugoRep

Python es un lenguaje de script desarrollado por Guido van Rossum.

Podemos codificar empleando programación lineal, estructurada y orientada a objetos (tengamos en cuenta que esta última es la que se ha impuesto en la actualidad).
Se cuenta con intérpretes de Python en múltiples plataformas: Windows, Linux, Mac etc. Se pueden desarrollar aplicaciones de escritorio como aplicaciones web. Empresas como Google, Yahoo, Nasa etc. utilizan este lenguaje para sus desarrollos (actualmente el creador de Python Guido van Rossum trabaja para Google.)

Se puede ejecutar instrucciones de Python desde la línea de comando o creando archivos con extensión *.py. Cuando uno comienza a aprender este lenguaje la línea de comandos nos provee una retroalimentación del resultado en forma inmediata.

El objetivo de este tutorial es presentar en forma progresiva los conceptos fundamentales de este lenguaje y poder analizar los problemas resueltos y codificar los problemas propuestos en este mismo sitio, sin tener que instalar en un principio el Python en su equipo (o luego de instalado poder avanzar con el tutorial en cualquier máquina conectada a internet).

Modificación de datos (App Engine).

Trabajaremos nuevamente con el problema de usuarios. Dispondremos un formulario que solicite la carga del nombre de un usuario y pasaremos a un segundo formulario donde mostraremos los datos actuales de dicho usuario. En una tercer página procedemos a modificar los datos ingresados.

import cgi
import wsgiref.handlers

from google.appengine.ext import webapp
from google.appengine.ext import db

class Formulario1(webapp.RequestHandler):
  def get(self):
   self.response.out.write("""
<html>
<head></head>
<body>
<form action="formulario2" method="post">
Ingrese nombre de usuario a modificar:
<input type="text" name="nombre"><br>
<input type="submit" value="Buscar"><br>
</form>
</body>
</html>
""")

class TablaUsuarios(db.Model):
  nombre=db.StringProperty()
  clave=db.StringProperty()

class Formulario2(webapp.RequestHandler):
  def post(self):
   self.response.out.write("<html><head></head><body>")
   nom=cgi.escape(self.request.get('nombre'))
   usuario=db.GqlQuery("select * from TablaUsuarios where nombre=:1",nom)
   usu=usuario.fetch(1)
   if len(usu)>0:
   self.response.out.write("""
<html>
<head></head>
<body>
<form action="procformulario2" method="post">
Nombre actual:
""")
   self.response.out.write("<input type=\"text\" name=\"nombre\" value=\""+usu[0].nombre+"\"><br>")
   self.response.out.write("Clave actual:")
   self.response.out.write("<input type=\"text\" name=\"clave\" value=\""+usu[0].clave+"\"><br>")
   self.response.out.write("<input type=\"hidden\" name=\"nombreoculto\" value=\""+usu[0].nombre+"\">")
   self.response.out.write("""
<input type="submit" value="Modificar"><br>
</form>
</body>
</html>
""")
   else:
   self.response.out.write("No existe un usuario con dicho nombre<br>")
   self.response.out.write("</body></body>")
  

class ProcFormulario2(webapp.RequestHandler):
  def post(self):
   self.response.out.write("<html><head></head><body>")
   nomoculto=cgi.escape(self.request.get('nombreoculto'))
   nom=cgi.escape(self.request.get('nombre'))
   cla=cgi.escape(self.request.get('clave'))  
   usuario=db.GqlQuery("select * from TablaUsuarios where nombre=:1",nomoculto)
   usu=usuario.fetch(1)
   if len(usu)>0:
   usu[0].nombre=nom
   usu[0].clave=cla
   usu[0].put()
   else:
   self.response.out.write("No existe un usuario con dicho nombre<br>")
   self.response.out.write("<a href=\"\\\">Principal</a>")  
   self.response.out.write("</body></body>")
  
def main():
  application = webapp.WSGIApplication([('/', Formulario1),
   ('/formulario2', Formulario2),
   ('/procformulario2', ProcFormulario2),  
   ],
   debug=True)
  wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
  main()

El segundo formulario debemos inicializar los atributos value de los dos controles text para que aparezcan cargados inicialmente con los datos actuales.

Por otro lado también es necesario definir un campo oculto donde almacenar el nombre de usuario actual, ya que si lo modifica no sabremos cual buscar:

class Formulario2(webapp.RequestHandler):
  def post(self):
   self.response.out.write("<html><head></head><body>")
   nom=cgi.escape(self.request.get('nombre'))
   usuario=db.GqlQuery("select * from TablaUsuarios where nombre=:1",nom)
   usu=usuario.fetch(1)
   if len(usu)>0:
   self.response.out.write("""
<html>
<head></head>
<body>
<form action="procformulario2" method="post">
Nombre actual:
""")
   self.response.out.write("<input type=\"text\" name=\"nombre\" value=\""+usu[0].nombre+"\"><br>")
   self.response.out.write("Clave actual:")
   self.response.out.write("<input type=\"text\" name=\"clave\" value=\""+usu[0].clave+"\"><br>")
   self.response.out.write("<input type=\"hidden\" name=\"nombreoculto\" value=\""+usu[0].nombre+"\">")
   self.response.out.write("""
<input type="submit" value="Modificar"><br>
</form>
</body>
</html>
""")
   else:
   self.response.out.write("No existe un usuario con dicho nombre<br>")
   self.response.out.write("</body></body>")

La tercer página recupera el usuario que ingresó en el primer formulario, pero rescatado del campo oculto. Procedemos seguidamente a modificar los datos rescatados de la tabla y confirmamos los nuevos datos llamando al método put:

class ProcFormulario2(webapp.RequestHandler):
  def post(self):
   self.response.out.write("<html><head></head><body>")
   nomoculto=cgi.escape(self.request.get('nombreoculto'))
   nom=cgi.escape(self.request.get('nombre'))
   cla=cgi.escape(self.request.get('clave'))  
   usuario=db.GqlQuery("select * from TablaUsuarios where nombre=:1",nomoculto)
   usu=usuario.fetch(1)
   if len(usu)>0:
   usu[0].nombre=nom
   usu[0].clave=cla
   usu[0].put()
   else:
   self.response.out.write("No existe un usuario con dicho nombre<br>")
   self.response.out.write("<a href=\"\\\">Principal</a>")  
   self.response.out.write("</body></body>")

Listado, Alta, Baja y Modificación (App Engine).

Ahora plantearemos todos los conceptos vistos para el manejo de una tabla de datos utilizando el Google App Engine.

Mostraremos un listado con una tabla con todos los nombres de usuarios y claves, dos hipervínculos uno para poder borrar el usuario y otro para poder modificar el registro. Por último dispondremos un hipervínculo para llamar a un formulario de alta de usuario.

import cgi
import wsgiref.handlers

from google.appengine.ext import webapp
from google.appengine.ext import db

class TablaUsuarios(db.Model):
  nombre=db.StringProperty()
  clave=db.StringProperty()

class Listado(webapp.RequestHandler):
  def get(self):
   self.response.out.write("<html><head></head><body>")
   self.response.out.write("<table border=\"1\">")
   self.response.out.write("<tr>")
  

self.response.out.write("<td>Usuario</td><td>Clave</td><td>Borrar</td><td>Modificar&l

t;/td>") 
   self.response.out.write("</tr>")
   usuarios=db.GqlQuery("select * from TablaUsuarios")
   for usu in usuarios:
   self.response.out.write("<tr>")
   self.response.out.write("<td>" + usu.nombre +"</td>")
   self.response.out.write("<td>" + usu.clave +"</td>")
   self.response.out.write("<td><a href=\"baja?nombre="+usu.nombre+"\">Borra?</a>"+"</td>")
   self.response.out.write("<td><a

href=\"formulariomodificacion?nombre="+usu.nombre+"\">Modifica?</a>"+"</td>")
   self.response.out.write("</tr>")
   self.response.out.write("<tr>")
   self.response.out.write("<td colspan=\"4\"><a href=\"formularioalta\">Alta</a></td>") 
   self.response.out.write("</tr>")  
   self.response.out.write("</table>")  
   self.response.out.write("</body></html>")

class FormularioAlta(webapp.RequestHandler):
  def get(self):
   self.response.out.write("""
<html>
<head></head>
<body>
<form action="alta" method="post">
Ingrese su nombre:
<input type="text" name="nombre"><br>
Ingrese su clave:
<input type="password" name="clave"><br>
<input type="submit" value="Alta"><br>
</form>
</body>
</html>
""")

class Alta(webapp.RequestHandler):
  def post(self):
   nom=cgi.escape(self.request.get('nombre'))
   cla=cgi.escape(self.request.get('clave'))
   usuario=TablaUsuarios()
   usuario.nombre=nom
   usuario.clave=cla
   usuario.put()
   self.redirect("/")

class Baja(webapp.RequestHandler):
  def get(self):
   nom=cgi.escape(self.request.get('nombre'))
   usuario=db.GqlQuery("select * from TablaUsuarios where nombre=:1",nom)
   usu=usuario.fetch(1)
   if len(usu)>0:
   usu[0].delete()
   self.redirect("/")
  
class FormularioModificacion(webapp.RequestHandler):
  def get(self):
   self.response.out.write("<html><head></head><body>")
   nom=cgi.escape(self.request.get('nombre'))
   usuario=db.GqlQuery("select * from TablaUsuarios where nombre=:1",nom)
   usu=usuario.fetch(1)
   if len(usu)>0:
   self.response.out.write("""
<html>
<head></head>
<body>
<form action="modificacion" method="post">
Nombre actual:
""")
   self.response.out.write("<input type=\"text\" name=\"nombre\" value=\""+usu[0].nombre+"\"><br>")
   self.response.out.write("Clave actual:")
   self.response.out.write("<input type=\"text\" name=\"clave\" value=\""+usu[0].clave+"\"><br>")
   self.response.out.write("<input type=\"hidden\" name=\"nombreoculto\" value=\""+usu[0].nombre+"\">")
   self.response.out.write("""
<input type="submit" value="Modificar"><br>
</form>
</body>
</html>
""")
   else:
   self.response.out.write("No existe un usuario con dicho nombre<br>")
   self.response.out.write("</body></body>")
  
class Modificacion(webapp.RequestHandler):
  def post(self):
   nomoculto=cgi.escape(self.request.get('nombreoculto'))
   nom=cgi.escape(self.request.get('nombre'))
   cla=cgi.escape(self.request.get('clave'))  
   usuario=db.GqlQuery("select * from TablaUsuarios where nombre=:1",nomoculto)
   usu=usuario.fetch(1)
   if len(usu)>0:
   usu[0].nombre=nom
   usu[0].clave=cla
   usu[0].put()
   self.redirect("/")

  
def main():
  application = webapp.WSGIApplication([('/', Listado),
   ('/formularioalta',FormularioAlta ),
   ('/alta',Alta ),  
   ('/baja', Baja),
   ('/formulariomodificacion', FormularioModificacion),
   ('/modificacion', Modificacion),  
   ],
   debug=True)
  wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
  main()

En la función main() debemos inicializar la lista que vincula las URL de las páginas y las clases que se ejecutan:

def main():
  application = webapp.WSGIApplication([('/', Listado),
   ('/formularioalta',FormularioAlta ),
   ('/alta',Alta ),  
   ('/baja', Baja),
   ('/formulariomodificacion', FormularioModificacion),
   ('/modificacion', Modificacion),  
   ],
   debug=True)
  wsgiref.handlers.CGIHandler().run(application)

La clase Listado es la que muestra la raiz del sitio y tiene por objetivo crear una tabla HTML con todos los usuarios almacenados en la TablaUsuarios. Además de imprimir cada registro disponemos un hipervínculo pasando como parámetro el nombre de usuario a borrar o modificar:

class Listado(webapp.RequestHandler):
  def get(self):
   self.response.out.write("<html><head></head><body>")
   self.response.out.write("<table border=\"1\">")
   self.response.out.write("<tr>")
  

self.response.out.write("<td>Usuario</td><td>Clave</td><td>Borrar</td><td>Modificar&l

t;/td>") 
   self.response.out.write("</tr>")
   usuarios=db.GqlQuery("select * from TablaUsuarios")
   for usu in usuarios:
   self.response.out.write("<tr>")
   self.response.out.write("<td>" + usu.nombre +"</td>")
   self.response.out.write("<td>" + usu.clave +"</td>")
   self.response.out.write("<td><a href=\"baja?nombre="+usu.nombre+"\">Borra?</a>"+"</td>")
   self.response.out.write("<td><a

href=\"formulariomodificacion?nombre="+usu.nombre+"\">Modifica?</a>"+"</td>")
   self.response.out.write("</tr>")
   self.response.out.write("<tr>")
   self.response.out.write("<td colspan=\"4\"><a href=\"formularioalta\">Alta</a></td>") 
   self.response.out.write("</tr>")  
   self.response.out.write("</table>")  
   self.response.out.write("</body></html>")

La clase FormularioAlta muestra los dos controles text y el botón submit, cuando se presiona dicho botón se procede a llamar a la URL alta:

class FormularioAlta(webapp.RequestHandler):
  def get(self):
   self.response.out.write("""
<html>
<head></head>
<body>
<form action="alta" method="post">
Ingrese su nombre:
<input type="text" name="nombre"><br>
Ingrese su clave:
<input type="password" name="clave"><br>
<input type="submit" value="Alta"><br>
</form>
</body>
</html>
""")

La clase Alta inicializa un objeto de la clase TablaUsuarios, procede a registrar los datos y mediante el método redirect redirige a la raiz del sitio (es decir la clase Listado):

class Alta(webapp.RequestHandler):
  def post(self):
   nom=cgi.escape(self.request.get('nombre'))
   cla=cgi.escape(self.request.get('clave'))
   usuario=TablaUsuarios()
   usuario.nombre=nom
   usuario.clave=cla
   usuario.put()
   self.redirect("/")

Cuando se presiona el hipervínculo "Borra?" en el listado se ejecuta la clase Baja y recibe como parámetro en el hipervínculo el nombre de usuario a borrar. Recuperamos el registro, llamamos al método delete y redirigimos nuevamente a la página de listado:

class Baja(webapp.RequestHandler):
  def get(self):
   nom=cgi.escape(self.request.get('nombre'))
   usuario=db.GqlQuery("select * from TablaUsuarios where nombre=:1",nom)
   usu=usuario.fetch(1)
   if len(usu)>0:
   usu[0].delete()
   self.redirect("/")

Cuando se presiona el hipervínculo "Modificación?" se ejecuta la clase FormularioModificacion, en este recuperamos el nombre de usuario e inicializamos los controles text y el campo oculto:

class FormularioModificacion(webapp.RequestHandler):
  def get(self):
   self.response.out.write("<html><head></head><body>")
   nom=cgi.escape(self.request.get('nombre'))
   usuario=db.GqlQuery("select * from TablaUsuarios where nombre=:1",nom)
   usu=usuario.fetch(1)
   if len(usu)>0:
   self.response.out.write("""
<html>
<head></head>
<body>
<form action="modificacion" method="post">
Nombre actual:
""")
   self.response.out.write("<input type=\"text\" name=\"nombre\" value=\""+usu[0].nombre+"\"><br>")
   self.response.out.write("Clave actual:")
   self.response.out.write("<input type=\"text\" name=\"clave\" value=\""+usu[0].clave+"\"><br>")
   self.response.out.write("<input type=\"hidden\" name=\"nombreoculto\" value=\""+usu[0].nombre+"\">")
   self.response.out.write("""
<input type="submit" value="Modificar"><br>
</form>
</body>
</html>
""")
   else:
   self.response.out.write("No existe un usuario con dicho nombre<br>")
   self.response.out.write("</body></body>")

Cuando se presiona el botón modificación del formulario anterior se ejecuta la clase Modificacion donde se procede a modificar el nombre y clave del usuario. Por último se redirige a la raiz del sitio:

class Modificacion(webapp.RequestHandler):
  def post(self):
   nomoculto=cgi.escape(self.request.get('nombreoculto'))
   nom=cgi.escape(self.request.get('nombre'))
   cla=cgi.escape(self.request.get('clave'))  
   usuario=db.GqlQuery("select * from TablaUsuarios where nombre=:1",nomoculto)
   usu=usuario.fetch(1)
   if len(usu)>0:
   usu[0].nombre=nom
   usu[0].clave=cla
   usu[0].put()
   self.redirect("/")

Si te ha gustado el artículo inscribete al feed clicando en la imagen más abajo para tenerte siempre actualizado sobre los nuevos contenidos del blog: