En el ultimo post, conseguimos enviar objetos javascript via JSON a nuestro servidor, la información es serializada en la base de datos en este capitulo.
Antes de empezar, dejarme allanar el camino, el schema (estructura) de la Base de datos es modificada de esta forma:
PYTHON:
-
class Book(models.Model):
-
isbn = models.CharField(maxlength=10, primary_key=True)
-
pub_date = models.DateField(’data published’)
La razón de este cambio la encontramos en que AWS devuelve ISBN-10 como ASIN, Podremos sacar provecho de ello, Otro cambio es la substitución de DateTimeField by DateField para el atributo pub_date. Django no soporta seamless database scheme hasta el momento. Debermos eliminar la basede datos y regenerar tal y como esta descrito. El username/password para la nueva database es admin/gelman como costumbre.
Es bastante molesto un error 500 sin ninguna razón, El servidor Web de Django se come la excepcion por naturaleza, podremos contralar el bug sospechoso con un codigo try/except como este:
PYTHON:
-
try :
-
// database access
-
except :
-
print sys.exc_info()[0]
Bien, InterfaceError o IntegrityError es el error que muestra en la inserción en la Base de datos, pero porque? las shells interactives son nuestras mejores amigas, podemos usar pdb o [HTML]python manage.py shell[HTML].
Mea culpa, olvidamos que el valor de regreso de get_or_create es una tupla, en vez de un objeto, y para la relación de muchos a muchos, no nos vale simplemente con el conjunto de valores de la lista, necesitamos usar un metodo add despues de que el objeto sea contruido:
PYTHON:
-
for item in simplejson.loads(request.POST[‘items’]):
-
publisher, created = Publisher.objects.get_or_create(name=item[‘publisher’])
-
authors = [Author.objects.get_or_create(name=au) for au in item[‘authors’]]
-
authors = [author for (author, created) in authors];
-
y,m,d = [int(x) for x in item[‘pub_date’].split(‘-’)]
-
pub_date = date(y, m, d)
-
book, created = Book.objects.get_or_create(isbn=item[‘isbn’], name=item[‘title’],
-
pages=300, pub_date=pub_date, publisher=publisher)
-
book.authors.add(*authors)
-
#print sys.exc_info()[0]
-
return HttpResponseRedirect(‘/admin/library/book/’)
Llegamos al final, debemos hacer un redirect del navegador a la nueva url.
Al parecer la base de datos esta actualizada pero la pagina no se redirije, desde que es lanzado el post en una petición AJAX, necesitamos enviar un objeto JSON como respuesta. En el servidor, simplejson.dump es usado:
PYTHON:
-
xhr = {’succeed’: [], ‘failed’: []};
-
for item in simplejson.loads(request.POST[‘items’]):
-
# … ….
-
try :
-
book, created = Book.objects.get_or_create(isbn=item[‘isbn’], name=item[‘title’],
-
pages=300, pub_date=pub_date, publisher=publisher)
-
book.authors.add(*authors)
-
except :
-
xhr[‘failed’].append(item[‘title’])
-
xhr[’succeed’].append(item[‘title’])
-
-
return HttpResponse(simplejson.dumps(xhr), mimetype=‘text/javascript’);
En el cliente, evaluaremos el string JSON que propaga los nodos del DOM.
JavaScript:
-
dojo.xhrPost({
-
url: dojo.byId(“book_form”).action,
-
content: { items: dojo.toJson(formdata) },
-
}).addCallback(function(response) {
-
var result = dojo.fromJson(response);
-
var messages = dojo.query(“ul[@class=messagelist]”)[0]
-
dojo.forEach(result.failed, function(item) {
-
var msg = document.createElement(“li”);
-
msg.innerHTML = “<li><em>” + item + “</em> <strong>failed</strong> to add.</li>”
-
messages.appendChild(msg);
-
});
-
dojo.forEach(result.succeed, function(item) {
-
var msg = document.createElement(“li”);
-
msg.innerHTML = “<em>” + item + “</em> successfully added.”
-
messages.appendChild(msg);
-
});
-
});
El resultado final tiene esta pinta:

check r19 para los detalles.