Bien, vamos a hacer algunos pasos, hize un codigo con un buscador simple en ajax, no es gran cosa pero es lo básico para que puedas partir desde ese buscador y agregarle mas opciones. me apoye de Jquery y de Jquery UI autocomplete
Paso 1
creando una aplicacion para el ajax.
Ejecuta este comando: python manage.py startapp ajax
esto creara una carpeta 'ajax', edita el archivo views.py y agrega este contenido:
from django.shortcuts import render
from django.http import HttpResponseBadRequest, HttpResponse, HttpRequest
from django.contrib.auth.models import User
from django.core import serializers
import re
def search(request):
# si no es una peticion ajax, devolvemos error 400
if not request.is_ajax() or request.method != "POST":
return HttpResponseBadRequest()
# definimos el termino de busqueda
q = request.POST['q']
#verificamos si el termino de busqueda es un documento de identidad
match = re.match(r'^(?P<CI>[0-9]{2,})$', q)
isCI = (False, True)[match != None]
# generamos la query
if isCI:
users = User.objects.filter(CI=match.groupdict()['CI'])
else:
users = User.objects.filter(username__contains=q)
# seleccionamos las columnas que deseamos obtener para el json
user_fields = (
'username',
'email',
'CI'
)
# to json!
data = serializers.serialize('json', users, fields=user_fields)
# eso es todo por hoy ^^
return HttpResponse(data, content_type="application/json")
guardalo.
Abre el archivo urls.py y agrega este codigo:
url(r'^ajax/search/', view='ajax.views.search'),
Ahora podras acceder a /ajax/search/ con una petición ajax, he agregado una condicional para que cuando no detecte una peticion ajax devuelva 400
Nota: yo supuse que el identificador de identididad esta en la tabla auth_users, si es asi entonces Agrega este codigo al archivo /ajax/init.py:
from django.db import models
from django.contrib.auth.models import User
ci_field = models.IntegerField()
ci_field.contribute_to_class(User, 'CI')
Paso 2
Agregando el html, js y css.
Donde requieras el buscador, en alguna plantilla, agrega este codigo:
<div id="container">
<div class="search">
<div class="searchbox">
<label>Buscar un estudiante:</label>
<span class="info">(Puede ser un nombre o el id de identidad)</span>
<input id="search_input" type="text" name="q">
{% csrf_token %}
</div>
<div class="results">
<h1 class="error"></h1>
<div class="wrapper"></div>
</div>
</div>
</div>
Agrega los recursos a tu etiqueta <head>
:
<link rel="stylesheet" href="{{ STATIC_URL }}styles.css">
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
<script type="text/javascript" src="https://code.jquery.com/ui/1.11.2/jquery-ui.min.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}script.js"></script>
Nota: los recursos los tengo alojados en /django/app/static/
si no tienes esto, en setings.py agrega:
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static"),
)
y en INSTALLED_APPS
agrega:
'django.contrib.staticfiles',
el código de /static/script.js es:
function __init()
{
$('#search_input')
.val('')
.focus()
.keyup(function(){
if(!$.trim($(this).val()))
$('.results .error').empty().hide();
});
var cache = {};
$('#search_input').autocomplete({
minLength: 2,
select: function( event, ui ) {
return false;
},
open: function() {
$('.results .wrapper').html($(this).autocomplete("widget").html());
$(this).autocomplete("widget").hide();
},
source: function( request, response ) {
if (cache[request.term]) {
response(cache[request.term]);
return;
}
$.ajax({
dataType : 'json',
method : 'POST',
url : '/ajax/search/',
data : {
q : encodeURIComponent(request.term),
csrfmiddlewaretoken : $('input[name=csrfmiddlewaretoken]').val()
},
success : function(data) {
var users = [];
for(var x in data)
{
users.push({
username : data[x].fields['username'],
CI : data[x].fields['CI'],
email : data[x].fields['email']
});
}
cache[request.term] = users;
response(users);
}
});
},
response: function(event, ui) {
if (ui.content.length === 0) {
$('.results .error').html('No se encontraron resultados').show();
$('.results .wrapper').empty();
}
else
$('.results .error').empty().hide();
}
}).autocomplete('instance')._renderItem = function(ul, item) {
var user_tmpl = $('<div />')
.addClass('user')
.append('<a href="/" />').find('a').addClass('username').html(item.username)
.parent()
.append('<span class="identity"><strong>Identidad:</strong><span></span></span>')
.find('.identity > span').append(item.CI)
.parent().parent()
.append('<span class="email"><strong>Email:</strong><span></span></span>')
.find('.email > span').append(item.email)
.parent().parent();
return $('<div></div>')
.data('item.autocomplete', item)
.append(user_tmpl)
.appendTo(ul);
};
}
$(document).ready(__init);
el código de /static/styles.css es:
body{
margin: 0;
padding: 0;
font-family: monospace;
}
#container{
width: 1000px;
margin: 0 auto;
margin-top: 30px;
}
.ui-helper-hidden-accessible{ display:none!important; }
.search{
background: #f1f1f1;
border-bottom: 1px solid #CCCCCC;
border-radius: 4px;
padding: 10px;
width: 750px;
margin: 0 auto;
}
.search .searchbox{
border-bottom: 1px solid #DDDDDD;
padding-bottom: 10px;
}
.search .searchbox label{
display: block;
font-weight: bold;
margin-bottom: 4px;
}
.search .searchbox .info{
color: #444;
display: block;
font-size: 11px;
}
.search .searchbox input{
border-radius: 0;
border: 1px solid #DDD;
border-bottom-width: 2px;
color: #333;
font-weight: bold;
font-size: 14px;
padding: 7px 10px;
width: 300px;
}
.search .results{
border-top: 1px solid #FFFFFF;
min-height: 20px;
}
.search .results .error{
display: none;
background: #e74c3c;
border-bottom: 2px solid #c0392b;
color: #FFFFFF;
padding: 7px 14px;
}
.search .results .wrapper{
max-height: 400px;
overflow: auto;
}
.search .results .wrapper div.user
{
margin: 10px;
}
.search .wrapper div.user .username,
.search .wrapper div.user .email,
.search .wrapper div.user .identity{
display: block;
}
.search .wrapper div.user .email,
.search .wrapper div.user .identity{
color: #555;
font-size: 11px;
}
.search .wrapper div.user .username{
color: #2980b9;
}
.search .wrapper div.user .username{
font-weight: bold;
font-size: 15px;
}
quedando algo asi:
Un ejemplo de este buscador simple lo puedes ver online en http://jsfiddle.net/m880wdnu/embedded/result/ obviamente este demo no utiliza ajax por obvias razones.