jQuery Autocomplete + Django + AJAX
Ahora voy a explicar algo técnico pero estético, como utilizar la plugin de jQuery Autocomplete con Django+AJAX, con ella se pueden conseguir efectos como este;
jQuery Autocomplete
Trataré de hacer una consulta por AJAX a una URL cuando tipee 3 o más letras, el código puede ser el siguiente;
$('input').autocomplete({ minLength:3, source: function(req, add){ $.ajax({ url: '/ajax/url/', async: false, dataType:'json', type:'POST', data: { start: function() { return $(this).val(); }, }, success: function(data) { //create array for response objects var suggestions = []; //process response $.each(data.items, function(i, val){ suggestions.push(val[0]); }); //pass array to callback add(suggestions); } }); } }); |
Donde:
- input: Será el selector del campo de texto al que queremos aplicarle el plugin.
- minLength: La longitud mínima para hacer la consulta.
- ‘/ajax/url/’: La URL donde haremos la consulta.
- start: Va a ser el valor actual del campo de texto, el texto que hemos tipeado y por el que queremos buscar.
La vista podría estar definida como sigue:
def search(request): if request.method=='GET' or not request.POST.__contains__('start'): return HttpResponseForbidden() # Hacemos la consulta para aquellos elementos que empiecen por start ordenados por nombre query = Model.objects.filter(name__istartswith=request.POST['start']).order_by('name') # Serializamos objects = u'{items: [\n' for i in query: objects += u'{"0":"%s"},\n' % (i.name.replace('"','')) objects=objects.strip(",\n"); objects+=u']}\n' return HttpResponse(objects,mimetype="text/plain") |
También se pueden utilizar serializadores para pasar la información a JSON, pero en este caso he preferido hacerlo a mano.
Para más información visita la página de jQuery.
Here is the attachments of this Post

Hola, justamente estoy tratando de colocar una búsqueda con autocompletado de unos de los campos de mi modelo, pero no he logrado hacerlo. Me llama la atención esta técnica que has usado. Sin embargo, no entiendo varias cosas. Será que puedes pasarme un ejemplo simple completo para poder ver todas las cosas necesarias para que funcione. Muchas gracias, mi correo es: serena.luna@gmail.com
Hola Serena,
escríbeme por aquí las dudas que encuentres y estaré encantado de resolverlas
1saludo
Bueno, por ejemplo en Django según lo que he entendido hasta ahora se debe tener: un modelo, una vista y su correspondiente plantilla. En este ejemplo veo la vista, y asumo que el script que colocaste debe ir en la plantilla. Sin embargo, no veo como asociar la plantilla con la vista (esto debería ser en urls.py), por eso te pedía un ejemplo sencillo completo para ver todo en conjunto funcionando. Gracias por ayudarme.
Te explico, en este caso necesitarías dos vistas:
* Una que te devuelva la plantilla renderizada con el contenido js y HTML.
* Otra que se encarga de resolver las consultas para el autocompletado, que es la que he escrito arriba.
Un ejemplo en urls.py;
####
from django.conf.urls.defaults import *
urlpatterns = patterns(‘myapp.views’,
url(r’^/url/$’, ‘vista_normal’,), #1
url(r’^/ajax/url/$’, ‘autocompletado_ajax’,), #2
)
####
#1 Es la vista que renderiza la plantilla, mediante render_to_response (p.e) y
#2 Es la vista que he expuesto arriba
¿Más claro?
Creo que no he entendido, porque lo he colocado pero no funciona.
Lo he colocado así:
# views.py
#vista 1
def search_form(request):
return render_to_response(‘search_prod.html’,context_instance = RequestContext(request))
#vista 2
def search(request):
if request.method==’GET’ or not request.POST.__contains__(‘start’):
return HttpResponseForbidden()
# Hacemos la consulta para aquellos elementos que empiecen por start ordenados por nombre
query = Producto.objects.filter(descripcion__icontains=request.POST['start']).order_by(‘descripcion’)
# Serializamos
objects = u’{items: [\n'
for i in query:
objects += u'{"0":"%s"},\n' % (i.descripcion.replace('"',''))
objects=objects.strip(",\n");
objects+=u']}\n’
return HttpResponse(objects,mimetype=”text/plain”)
###########################################################
#urls.py
from django.contrib import admin
from django.conf import settings
admin.autodiscover()
urlpatterns = patterns(”,
url(r’^search/’,'principal.views.search_form’),
url(r’^ajax/search’,'principal.views.search’),
)
###########################################################
#search_prod.html
{% extends ‘base.html’ %}
{% block script %}
{% endblock %}
$(‘input’).autocomplete({
minLength:2,
source: function(req, add){
$.ajax({
url: ‘/ajax/search/’,
async: false,
dataType:’json’,
type:’POST’,
data: {
start: function() { return $(this).val(); },
},
success: function(data) {
//create array for response objects
var suggestions = [];
//process response
$.each(data.items, function(i, val){
suggestions.push(val[0]);
});
//pass array to callback
add(suggestions);
}
});
}
});
{% block titulo %} Consultar precio de productos {% endblock %}
{% block encabezado %}
Consultar precio de productos
{% endblock %}
{% block contenido %}
{% endblock %}
###############################################################
Pero aún no funciona, puedes ver el error?
Qué mensaje de error te llega? En el inspector (para Chrome) o firebug (Firefox) puedes ver el resultado de la petición ajax.
No me dice el error, simplemente no hace el autocompletado. Pero no viste ningún error en mi código.
Ei si! Olvidaste el campo input, tienes que ponerlo
Disculpa fue que no se copió completo, lo vuelvo a pegar aqui:
#search_prod.html
{% extends ‘base.html’ %}
{% block script %}
{% endblock %}
$(‘input’).autocomplete({
minLength:2,
source: function(req, add){
$.ajax({
url: ‘/ajax/search/’,
async: false,
dataType:’json’,
type:’POST’,
data: {
start: function() { return $(this).val(); },
},
success: function(data) {
//create array for response objects
var suggestions = [];
//process response
$.each(data.items, function(i, val){
suggestions.push(val[0]);
});
//pass array to callback
add(suggestions);
}
});
}
});
{% block titulo %} Consultar precio de productos {% endblock %}
{% block encabezado %}
Consultar precio de productos
{% endblock %}
{% block contenido %}
{% endblock %}
Bienn creo que te falta una cosa, el campo input en el bloque contenido, simplemente pon este código: http://dpaste.com/829405/
Lo coloque así:
{% block contenido %}
{% endblock %}
no se le debe colocar id=’start’ o name=’start’?
no me lo muestra en el comentario, por qué?
Bueno es igual al que me enviaste pero le agrego id=’start’
En el comentario no te lo muestra porque interpreta el HTML xD
No es necesario, “start” sólo se utiliza cómo parámetro a enviar, al el id o name del input no se usa.
Se lo quite y lo vuelvo a probar, pero sigue sin funcionar
No sé que más hacer…
Comparte conmigo una carpeta en Dropbox con el proyecto que lo veo en un momento, utiliza mi email rdugomartin@gmail.com
Muchas gracias, ahora está funcionando al 100%. Gracias por tu tiempo.
De nada Serena, recuerda mostrarme ese proyecto (u otro) cuando esté en producción.
Un saludo:)
Y qué era el error de Serena? lo que pasa es que también lo estoy implementando en mi código y tampoco me sale el autocomplete.