**Estimados, por aquí les dejo este pequeño tutorial que hice conforme voy avanzando ,por si a alguien le sirve, es sobre como crear un CRUD usando Python(Django) AJAX MySQL.
*Es de mencionar que Django posee un sitio de administracion por default, pero puede resultar mas didactico aprender a crearlo por nosotros mismos, asi se comprende mejor la arquitectura MVC y la forma de programacion Web en Python, en la presentacion usando AJAX con conexión a base de datos MySQL.
Recursos:
_________________________________________________________________
Se uso:
*Python 2.6
*Framework Django V.1.0
*MySQL 5.1
Libro de django v.1 | El Libro de Django | python | espanol | lo pueden encontrar aquí:
http://www.svcommunity.org/forum/programacioacuten/lista-de-recursos/*Como sugerencia, prefiero usar el Framework en Linux, por la rapida configuracion y que ya tiene instalado Python y MySQL.
Introduccion:
______________________________________________________________
Que es MVC?
Modelo Vista Controlador (MVC) es un patrón de arquitectura de software que separa los datos de una aplicación, la interfaz de usuario, y la lógica de negocio en tres componentes distintos. El patrón de llamada y retorno MVC (según CMU), se ve frecuentemente en aplicaciones web, donde la vista es la página HTML y el código que provee de datos dinámicos a la página. El modelo es el Sistema de Gestión de Base de Datos y la Lógica de negocio, y el controlador es el responsable de recibir los eventos de entrada desde la vista.
Fuente:
http://es.wikipedia.org/wiki/Modelo_Vista_Controlador_______________________________________________________________
Que es un CRUD?
En computación CRUD es el acrónimo de Crear, Obtener, Actualizar y Borrar (del original en inglés: Create, Read, Update and Delete). Es usado para referirse a las funciones básicas en bases de datos o la capa de persistencia en un sistema de software.
Fuente:
http://es.wikipedia.org/wiki/CRUD_____________________________________________________________
Por que un CRUD?
El CRUD esta presente casi siempre en cualquier sistema de usuario normal y siempre en el sistema de usuario administrador, sea este escritorio, Web, sin importar el lenguaje.
_____________________________________________________________
Resumiendo se hara lo siguiente:
*Ejemplo de un modelo sencillo en django.
*Ejemplo de vistas en django
-Actualizar
-Eliminar
-Editar
-Consultar
*Uso de plantillas en Django con respecto a las vistas.
-Extendiendo de otras plantillas
-Uso de validaciones en la plantilla usando django
-Uso de variables enviadas desde la vista a la plantilla.
-AJAX
-Validaciones en ajax
-ajax en consultas,eliminar,actualizacion y edicion de los registros.
*Configurando urls.py para uso ccs y Javascript desde Django.
[Las primeras 100 paginas del libro django v.1 abarcan parte de este contenido, pero como ejemplo interesante solo muestra como hacer una consulta a una base de datos y no muestra el uso del Framework con AJAX]
_______________________________________________________________________
Parte del resultado final:
*Haciendo de caso que esta instalado Python,Django, MySQL.
-Creamos un directorio crud_django.
En la consola:
>mkdir crud_django
>cd crud_django
>django-admin.py startproject miproyecto
Crea un directorio 'miproyecto' con la siguiente estructura:
/miproyecto
/__init__.py
/manage.py
/settings.py
/urls.py
*Nos cambiamos al directorio 'miproyecto' desde la consola y ejecutamos:
python manage.py runserver
Ya debe estar funcionando el servidor de django.[Este servidor solo procesa una peticion a la vez]
http://localhost:8000/
*CONFIGURANDO LA CONEXION A LA BASE DE DATOS EN EL ARCHIVO 'SETTINGS.PY'[solo se hace una vez y ya!!]
*Quedaria la siguiente configuracion:
DATABASE_ENGINE = 'mysql' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'.
DATABASE_NAME = 'bd_prueba' # Or path to database file if using sqlite3.
DATABASE_USER = 'user' # Not used with sqlite3.
DATABASE_PASSWORD = 'password' # Not used with sqlite3.
DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3.
DATABASE_PORT = '3306' # Set to empty string for default. Not used with sqlite3.
Una forma para confirmar que la base de datos ha sido bien configurada correctamente es la siguiente, estando en el directorio 'miproyecto', Python nos da la oportunidad de ejecutar el shell dentro del proyecto creado 'miproyecto' y asi interactuar con los archivos creados.
/miproyecto> python manage.py shell
Python 2.6.5 (r265:79063, Jul 5 2010, 11:47:21)
[GCC 4.5.0 20100604 [gcc-4_5-branch revision 160292]] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.db import connection
>>> cursor=connection.cursor()
*Si ejecutamos estos comandos y no tenemos ningun problema, es porque tenemos configurada correctamente la base de datos en el archivo 'settings.py'.
*CREANDO LA APLICACION
/miproyecto> python manage.py startapp micrud
*Creara un directorio 'micrud':
/micrud
__init__.py
models.py
views.py
*DEFINIENDO DONDE ESTARAN LAS PLANTILLAS
*Crear el directorio 'templates' en la siguiente ruta:
/crud_django/miproyecto/
Y luego editar el archivo 'settings.py':
TEMPLATE_DIRS = (
'/home/eduardo/crud_django/miproyecto/templates',
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)
Dentro de /home/eduardo/crud_django/miproyecto/templates crearemos los directorios para CCS y Javascript
/templates
/ccs
/js
*CREANDO EL MODELO
En /home/eduardo/crud_django/miproyecto/micrud/models.py
from django.db import models
class Agenda(models.Model):
nombre = models.CharField(maxlength=30)
apellido = models.CharField(maxlength=40)
pais = models.CharField(maxlength=30)
correo = models.EmailField()
def __str__(self):
return ' %s %s' % (self.nombre, self.pais)
En el archivo 'settings.py' , instalando el modelo, agregando la siguiente linea: ''miproyecto.micrud',
donde 'miproyecto' es el nombre de mi proyecto y 'micrud' es el nombre de mi app.
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'miproyecto.micrud',
)
*Validando la sintaxis del modelo:
crud_django/miproyecto> python manage.py validate
0 errors found.
Si no hay problema..ejecutamos
crud_django/miproyecto> python manage.py sqlall micrud
BEGIN;
CREATE TABLE `micrud_agenda` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`nombre` varchar(30) NOT NULL,
`apellido` varchar(40) NOT NULL,
`pais` varchar(30) NOT NULL,
`correo` varchar(75) NOT NULL
);
COMMIT;
Lo interesante:
-Nos crea una llave primaria por default llamada 'id'.
sqlall no ha tocado o creado aun la base de datos en MySQL, solo muestra como queda CREATE TABLE.
*Creando las tablas de MySQL desde el Framework[Mencionar que ya tengo creada una base de datos llamada bd_prueba que se determino en la configuracion de la base de datos en 'settings.py']
crud_django/miproyecto> python manage.py syncdb
Creating table auth_message
Creating table auth_group
Creating table auth_user
Creating table auth_permission
Creating table django_content_type
Creating table django_session
Creating table django_site
Creating table micrud_agenda
You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no): yes
Username (Leave blank to use 'eduardo'): admin
E-mail address: correo@server.com
Password:
Password (again):
Superuser created successfully.
Installing index for auth.Message model
Installing index for auth.Permission model
Loading 'initial_data' fixtures...
No fixtures found.
*Nos crea la tabla
Creating table micrud_agenda
Y un superusers con las tablas de privilegios por si queremos usar el sitio de administracion por default de django, pero este no se explica en este momento.
*CREANDO EL CRUD
*Creando la consulta:
-Dentro de /templates/css se ha creado un archivo llamado 'estilo.css' no colocare el codigo porque es bastante.
-Se creara una consulta usando un combo y otra introduciendo el registro a buscar:
Creando el archivo ajax dentro de /templates/js lo llamaremos ajax.js 'function ConsultaFiltrado(Pag,objId,objIdVacio)' se usara para consultar usando el combo o el valor introducido por el usuario.
En el archivo urls.py se debe editar para que django encuentre los archivos ccs y javascript y a la vez defino donde esta las vistas y que funcion de 'views.py' deben ejecutar.
from django.conf.urls.defaults import *
import settings
urlpatterns = patterns('',
(r'^buscar/$','miproyecto.micrud.views.consulta'),
(r'^combo/$','miproyecto.micrud.views.combo'),
(r'css/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': settings.STATIC_ROOT 'templates/css'}),
(r'js/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': settings.STATIC_ROOT 'templates/js'}),
# Example:
# (r'^miproyecto/', include('miproyecto.foo.urls')),
# Uncomment this for admin:
# (r'^admin/', include('django.contrib.admin.urls')),
)
Ahora en 'settings.py' al final del archivo debo agregar la ruta donde estan mis archivs js y css.
STATIC_ROOT = '/home/eduardo/crud_django/miproyecto/'
STATIC_ROOT 'templates/',
http://snatverk.blogspot.com/2011/01/anadir-hoja-de-estilo-en-django.htmlajax.js
/*____________________________________________________________________*/
function objetoAjax(){
var xmlhttp=false;
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (E) {
xmlhttp = false;
}
}
if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
xmlhttp = new XMLHttpRequest();
}
return xmlhttp;
}
/*____________________________________________________________________*/
function ConsultaFiltrado(Pag,objId,objIdVacio){
divVacios=document.getElementById(objIdVacio);
if (document.formulario.q.value=="")
{
divVacios.innerHTML ="<div class='mensaje' align='justify'>Complete la informacion</div>"
}
else
{
divResultado = document.getElementById(objId);
valor=document.formulario.q.value
ajax=objetoAjax();
ajax.open("GET",Pag "?q=" valor);
ajax.onreadystatechange=function() {
if (ajax.readyState==4) {
divResultado.innerHTML = ajax.responseText
divVacios.innerHTML =""
}
}
ajax.send(null)
}
}
/*____________________________________________________________________*/
Creando las vistas:
En el archivo views.py:
# Create your views here.
#from django.db.models import Q
from django.shortcuts import render_to_response
from models import Agenda
################################################################################
def consulta(request):
consulta = request.GET.get('q', '')
if consulta:
results=Agenda.objects.filter(pais=consulta).order_by('id')
return render_to_response("consulta.html", { "results": results,"consulta": consulta})
return render_to_response("consulta.html", { "results": [],"consulta": consulta})
##############################################################################
def combo(request):
query = request.GET.get('q', '')
elementos= Agenda.objects.values('pais').distinct()
if query:
results=Agenda.objects.filter(pais=query)
return render_to_response("consulta_combo.html",{"results": results,"query": query,"elementos": elementos} )
return render_to_response("consulta_combo.html",{"results": elementos,"query": query,"elementos": elementos} )
################################################################################
Dentro del diretorio /template crearemos un archivo html que servira de base para todos los demas, se extendera y no sera necesario estar repitiendo codigo en cada archivo:
Lo interesante {% block X%}{% endblock %} puedo definir contenido en “la base” y luego solo “extentenderlo” desde cualquier archivo html con {% extends "base.html" %}
base.html
{# Comentario #}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>{% block title %}{% endblock %}</title>
{% block javascript %}<script language="Javascript" src="/js/scripts.js"></script>{% endblock %}
{% block ajax %}<script language="Javascript" src="/js/ajax.js"></script>{% endblock %}
{% block css %}<link rel="stylesheet" href="/css/estilo.css" type="text/css"/>{% endblock %}
<meta name="Title" content="Django[Python]"/>
<meta name="Author" content="edu_guerr" />
<meta name="Subject" content="Django[Python]" />
<meta name="Description" content="Aprendiendo Django[Python]" />
<meta name="Keywords" content="django,python,programacion" />
<meta name="Language" content="Spanish" />
<meta name="Revisit" content="15 days" />
<meta name="Distribution" content="Local" />
<meta name="Robots" content="All" />
</head>
<body>
{% block contenido %}
{% block encabezado %}{% endblock%}
{% endblock %}
{% block pie %} <hr><p>Creando un [CRUD] con [Django]</p>{% endblock %}
</body>
</html>
La plantilla para la consulta:
Consulta.html
{% extends "base.html" %}
{% block title %}Django[Python]{% endblock %}
{% block contenido %}
<div id="resultado" >
{% block encabezado %}<h1>Busqueda filtrada</h1>{% endblock%}
<form class='estiloform' name='formulario' action="" onsubmit="ConsultaFiltrado('http://localhost:8000/buscar/','resultado','Vacios'); return false">
<div><label for="p">Buscar: </label></div> <div><input type="text" name="q" value="{{ consulta|escape }}"></div>
<div><input type="submit" value="Aceptar"></div>
{% if consulta %}
<h1>Resultados para "{{ consulta|escape }}":</h1>
{% if results %}
<table id='tabla_'>
<tr><td>Nombre</td><td>Apellido</td><td>Correo</td><td>Pais</td></tr>
{% for agenda in results %}
<tr><td>{{agenda.nombre|upper}}</td><td >{{agenda.apellido|upper}}</td>
<td>{{agenda.correo|upper}}</td><td >{{agenda.pais|upper}} </td>
</tr>
{% endfor %}
</table>
{% else %}
<div class="mensaje" align="justify">No hay resultados</div>
{% endif %}
{% endif %}
</form>
<div id=Vacios align="center" ></div>
{% endblock %}
La plantilla para la consulta usando el combo:
Consulta_combo.html
{% extends "base.html" %}
{% block title %}Django[Python]{% endblock %}
{% block contenido %}
<div id="resultado" >
{% block encabezado %}<h1>Busqueda filtrada usando combo</h1>{% endblock%}
<form class='estiloform' name='formulario' action="" >
<div><label for="q">Buscar: </label></div>
<SELECT NAME="q" onChange="ConsultaFiltrado('http://localhost:8000/combo/','resultado','Vacios'); return false">
<OPTION VALUE= "" >Seleccione</OPTION>
{% for agenda in elementos %}<OPTION VALUE= '{{agenda.pais}}' >{{agenda.pais}}</OPTION>{% endfor %}
</SELECT>
{% if query %}
<h2>Resultados para "{{ query|escape }}":</h2>
{% if results %}
<table id='tabla_'>
<tr><td>Nombre</td><td>Apellido</td><td>Correo</td><td>Pais</td></tr>
{% for agenda in results %}
<tr><td>{{agenda.nombre|upper}}</td><td >{{agenda.apellido|upper}}</td>
<td>{{agenda.correo|upper}}</td><td >{{agenda.pais|upper}} </td></tr>
{% endfor %}
</table>
{% else %}
<div class="mensaje" align="justify">No hay resultados</div>
{% endif %}
{% endif %}
</form>
<div id=Vacios align="center" ></div>
{% endblock %}
</div>
- {% extends "base.html" %} extiendo del archivo base.html
-"ConsultaFiltrado('http://localhost:8000/buscar/','resultado','Vacios'); return false" funcion que tengo definia en ajax.js
-onChange="ConsultaFiltrado('http://localhost:8000/combo/','resultado','Vacios'); return false" la misma funcion , solo que se llama desde el combo.
*Inserta unos registros en la base de datos bd_prueba en la tabla micrud_agenda
Y en el navegador:
http://localhost:8000/buscar/
http://localhost:8000/combo
-buscar y combo son los nombrres que se definieron en views.py, aquí hace su trabaja urls.py cuando se llama a 'buscar' o 'combo' define que mostrar.
Resultado: Hasta aqui tenemos una consulta a base de datos MySQL usando el Django AJAX y un poco de estilo:
AGREGAR UN REGISTRO:
La funcion ajax en el archivo ajax.js
function insertar(Pag,objId,objIdVacio) {
divVacios=document.getElementById(objIdVacio);
if (document.formulario.nom.value=="" || document.formulario.ape.value=="" || document.formulario.pais.value=="" || document.formulario.correo.value=="")
{
divVacios.innerHTML ="<div class='mensaje' align='justify'>Complete la informacion</div>"
}
else
{
divResultado = document.getElementById(objId);
nom=document.formulario.nom.value
ape=document.formulario.ape.value
pais=document.formulario.pais.value
correo=document.formulario.correo.value
ajax=objetoAjax();
ajax.open("GET",Pag "?nom=" nom "&ape=" ape "&pais=" pais "&correo=" correo,true);
ajax.onreadystatechange=function() {
if (ajax.readyState==4) {
divResultado.innerHTML = ajax.responseText
divVacios.innerHTML =""
}
}
ajax.send(null)
}
}
en /templates creando la plantilla:
agregar.html
{% extends "base.html" %}
{% block title %}Django[Python]{% endblock %}
{% block contenido %}
<div id="resultado" >
{% block encabezado %}<h1>Agregar un registro</h1>{% endblock%}
<form class='estiloform' name='formulario' action="" onsubmit="insertar('http://localhost:8000/agregar/','resultado','Vacios'); return false">
<table >
<tr><td><div><label for="q">Nombre:</label></td><td><input type="text" name="nom" value="{{ query|escape }}" onkeypress='return sololetra(event)'></div></td></tr>
<tr><td><div><label for="q">Apellido:</label></td><td><input type="text" name="ape" value="{{ query|escape }}" onkeypress='return sololetra(event)'></div></td></tr>
<tr><td><div><label for="q">Pais: </label></td><td><input type="text" name="pais" value="{{ query|escape }}" onkeypress='return sololetra(event)'><div></td></tr>
<tr><td><div><label for="q">Correo: </label></td><td><input type="text" name="correo" value="{{ query|escape }}"><div></td></tr>
<tr><td><div><input type="submit" value="Aceptar"></td><td></div>
<div><input type="reset" value="Limpiar"></div></td></tr></tr><tr>
</table>
</form>
{% if exito %}
<div class="mensaje" align="justify">Registro agregado</div>
{% endif %}
<div id=Vacios align="center" ></div>
{% endblock %}
</div>
-Siempre 'extendiendo' de base.html {% extends "base.html" %}, recordemos que en la base defino donde esta el archivo ajax.js
-onsubmit="insertar('http://localhost:8000/agregar/','resultado','Vacios'); return false funcion insertar que esta en ajax.js
Agregado la vista a views.py, recordemos que en este mismo archivo ya tenemos agragadas las vistas 'combo' y 'buscar'
def agregar_registro(request):
nom = request.GET.get('nom','')
ape = request.GET.get('ape','')
pais = request.GET.get('pais','')
correo = request.GET.get('correo','')
if nom:
if ape:
if pais:
if correo:
p=Agenda(nombre=nom,apellido=ape,pais=pais,correo=correo)
p.save()
return render_to_response('agregar.html',{"exito":True})
else:
return render_to_response('agregar.html')
Ahora es necesario definir cuando se va a llamar a la vista que recien se creo, eso se hace en 'urls.py'
agregaremos al archivo
(r'^agregar/$','miproyecto.micrud.views.agregar_registro'),
-Por ser una tupla, en Python requiere una ',' al final.
-Puedes ver como el string que se define en la tupla sigue lo siguiente:
miproyecto.micrud.views.agregar_registro=Proyecto-App-vista-nombre de la funcion.
El archivo urls.py quedaria asi:
from django.conf.urls.defaults import *
import settings
urlpatterns = patterns('',
(r'^buscar/$','miproyecto.micrud.views.consulta'),
(r'^combo/$','miproyecto.micrud.views.combo'),
(r'^agregar/$','miproyecto.micrud.views.agregar_registro'),
(r'css/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': settings.STATIC_ROOT 'templates/css'}),
(r'js/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': settings.STATIC_ROOT 'templates/js'}),
# Example:
# (r'^miproyecto/', include('miproyecto.foo.urls')),
# Uncomment this for admin:
# (r'^admin/', include('django.contrib.admin.urls')),
)
En el navegador:
http://localhost:8000/agregar/
Resultado:
ELIMINAR UN REGISTRO:
La funcion ajax en el archivo ajax.js
function eliminar(Pag,objId,idEliminar) {
divResultado = document.getElementById(objId);
var agree=confirm('Eliminar el registro #' idEliminar '?');
if (agree){
ajax=objetoAjax();
ajax.open("GET",Pag,true);
ajax.onreadystatechange=function() {
if (ajax.readyState==4) {
divResultado.innerHTML = ajax.responseText
}
}
ajax.send(null)
}
}
en /templates creando la plantilla:
eliminar.html
{% extends "base.html" %}
{% block title %}Django[Python]{% endblock %}
{% block contenido %}
<div id="resultado" >
{% block encabezado %}<h1>Eliminar registro</h1>{% endblock%}
<form class='estiloform' name='formulario' action="" >
{% if results %}
<table id="tabla_">
<tr><td>Nombre</td><td>Apellido</td><td>Correo</td><td>Pais</td><td>Accion</td></tr>
{% for agenda in results %}
<tr><td>{{agenda.nombre|upper}}</td><td>{{agenda.apellido|upper}}</td>
<td>{{agenda.correo|upper}}</td><td>{{agenda.pais|upper}} </td>
<td><a href=# onclick="eliminar('http://localhost:8000/eliminar/?codigo={{agenda.id}}','resultado','{{agenda.id}}'); return false">Eliminar</A></td>
</tr>
{% endfor %}
</table>
{% else %}
<p>Datos no encontrados</p>
{% endif %}
</form>
{% if exito %}
<div class="mensaje" align="justify">Registro #{{cod}} eliminado</div>
{% endif %}
{% endblock %}
</div>
-Siempre 'extendiendo' de base.html {% extends "base.html" %}, recordemos que en la base defino donde esta el archivo ajax.js
-onclick="eliminar('http://localhost:8000/eliminar/codigo={{agenda.id}}','resultado','{{agenda.id}}'); return false" funcion eliminar que esta en ajax.js
Agregado la vista a views.py, recordemos que en este mismo archivo ya tenemos agragadas las vistas 'combo' y 'buscar' y 'agregar'
def eliminar_registro(request):
cod=request.GET.get('codigo','')
results=Agenda.objects.all().order_by('id')
if cod:
p = Agenda.objects.get(id=cod)
p.delete()
return render_to_response('eliminar.html',{"results": results,"cod":cod,"exito":True})
return render_to_response('eliminar.html',{"results": results})
Ahora es necesario definir cuando se va a llamar a la vista que recien se creo, eso se hace en 'urls.py'
agregaremos al archivo la linea:
(r'^eliminar/$','miproyecto.micrud.views.eliminar_registro'),
donde 'miproyecto.micrud.views.eliminar_registro=Proyecto-App-vista-nombre de la funcion.
En el navegador:
http://localhost:8000/eliminar/
Mensajes de confirmacion antes de eliminar:
Accion realizada:
[ ]
EDITAR UN REGISTRO
Las funciones en el archivo ajax.js
function detalle_actualizar(Pag,objId,idActualizar) {
divResultado = document.getElementById(objId);
var agree=confirm('Actualizar el registro #' idActualizar '?');
if (agree){
ajax=objetoAjax();
ajax.open("GET",Pag,true);
ajax.onreadystatechange=function() {
if (ajax.readyState==4) {
divResultado.innerHTML = ajax.responseText
}
}
ajax.send(null)
}
}
/*____________________________________________________________________*/
function actualizar(Pag,objId,objIdVacio) {
divVacios=document.getElementById(objIdVacio);
if (document.formulario.nom.value=="" || document.formulario.ape.value=="" || document.formulario.pais.value=="" || document.formulario.correo.value=="")
{
divVacios.innerHTML ="<div class='mensaje' align='justify'>Complete la informacion</div>"
}
else
{
divResultado = document.getElementById(objId);
id=document.formulario.id.value
nom=document.formulario.nom.value
ape=document.formulario.ape.value
pais=document.formulario.pais.value
correo=document.formulario.correo.value
ajax=objetoAjax();
ajax.open("GET",Pag "?id=" id "&nom=" nom "&ape=" ape "&pais=" pais "&correo=" correo,true);
ajax.onreadystatechange=function() {
if (ajax.readyState==4) {
divResultado.innerHTML = ajax.responseText
divVacios.innerHTML =""
}
}
ajax.send(null)
}
}
Para esto se crearan dos archivos html
-ver_detalle.html y actualizar.html, el primero mostrara los registros de forma individual para actualizar, y el segundo mostrara todos los registros con opcion de elegir el que se desea editar.
ver_detalle.html
{% extends "base.html" %}
{% block title %}Django[Python]{% endblock %}
{% block contenido %}
<div id="resultado" >
{% block encabezado %}<h1>Actualizar un registro</h1>{% endblock%}
<form class='estiloform' name='formulario' action="" onsubmit="actualizar('http://localhost:8000/actualizar/','resultado','Vacios'); return false">
{% if results %}
<table id="tabla_" >
{% for agenda in results %}
<tr>
<tr><td><label for="q">Codigo:</label></td><td><input type="text" name="id" value="{{agenda.id}}" readonly></td></tr>
<tr><td><label for="q">Nombre:</label></td><td><input type="text" name="nom" value="{{agenda.nombre}}" onkeypress='return sololetra(event)'></td></tr>
<tr><td><label for="q">Apellido:</label></td><td><input type="text" name="ape" value="{{agenda.apellido}}" onkeypress='return sololetra(event)'></td></tr>
<tr><td><label for="q">Pais: </label></td><td><input type="text" name="pais" value="{{agenda.pais}}" onkeypress='return sololetra(event)'></td></tr>
<tr><td><label for="q">Correo: </label></td><td><input type="text" name="correo" value="{{agenda.correo}}"</td></tr>
<tr><td colspan=2><input type="submit" value="Actualizar"></td></tr></tr><tr>
</tr>
</table>
{% endfor %}
{% else %}
<p>Datos no encontrados</p>
{% endif %}
</form>
<div id=Vacios align="center" ></div>
{% endblock %}
</div>
actualizar.html
{% extends "base.html" %}
{% block title %}Django[Python]{% endblock %}
{% block contenido %}
<div id="resultado" >
{% block encabezado %}<h1>Actualizar un registro</h1>{% endblock%}
<form class='estiloform' name='formulario' action="." method="GET" >
{% if results %}
<table id="tabla_">
<tr><td>Nombre</td><td>Apellido</td><td>Correo</td><td>Pais</td><td>Accion</td></tr>
{% for agenda in results %}
<tr>
<td>{{agenda.nombre|upper}}</td><td>{{agenda.apellido|upper}}</td>
<td>{{agenda.pais|upper}}</td><td>{{agenda.correo|upper}}</td>
<td><a href=# onclick="detalle_actualizar('http://localhost:8000/actualizar/?id={{agenda.id}}','resultado','{{agenda.id}}'); return false">Actualizar</A>
</tr>
{% endfor %}
</table>
{% else %}
<p>Datos no encontrados</p>
{% endif %}
</form>
{% if exito %}
<div class="mensaje" align="justify">Registro #{{id}} actualizado</div>
{% endif %}
{% endblock %}
</div>
-Siempre se 'extendiende' de el archivo base html.
-Funciones definidas en ajax.js
onclick="detalle_actualizar('http://localhost:8000/actualizar/id={{agenda.id}}','resultado','{{agenda.id}}'); return false
actualizar('http://localhost:8000/actualizar/','resultado','Vacios'); return false"
La funcion en la vista
def actualizar_registro(request):
id = request.GET.get('id','')
results=Agenda.objects.all().order_by('id')
if id: # si solo obtengo el id , mostrar el detalle
if not request.GET.get('nom',''):
if not request.GET.get('ape',''):
if not request.GET.get('pais',''):
if not request.GET.get('correo',''):
results=Agenda.objects.filter(id=id).order_by('id')
return render_to_response('ver_detalle.html',{"results":results})
if id:
if request.GET.get('nom',''):
if request.GET.get('ape',''):
if request.GET.get('pais',''):
if request.GET.get('correo',''):
p=Agenda.objects.get(id=request.GET.get('id',''))# Que registro va a actualizar
p.id=request.GET.get('id','')
p.nombre=request.GET.get('nom','')
p.apellido=request.GET.get('ape','')
p.pais=request.GET.get('pais','')
p.correo=request.GET.get('correo','')
p.save()
results=Agenda.objects.all().order_by('id')
return render_to_response('actualizar.html',{"results":results,"id":id,"exito":True})
return render_to_response('actualizar.html',{"results":results})
En urls.py definimos la funcion creada en views.py.
(r'^actualizar/$','miproyecto.micrud.views.actualizar_registro'),
En el navegador:
http://localhost:8000/actualizar/
Todos los registros:
Editando de forma individual:
Regresa al formulario principal:
[ ]
Algunas cosas que resaltar:
-Lo interesante es que cuando configuramos el archivo 'settings.py' solo nos debemos preocupar por crear las plantillas, funciones en la vista y definir las rutas en urls.py
-Nunca mas se habla de la conexión a la base de datos, solo se define una vez los parametros y ya.
-Si alguien le interesa el codigo completo mandenme un mp y se los envio completo, junto al archivo css.
-Espero les sirva, y mencionar que a veces por un pequeño error nuestro, de sintaxis o una ruta mal puesta ,no podria funcionar
-Se debe tener cuidado con la Indentación en Python.