Mostrando entradas con la etiqueta ajax. Mostrar todas las entradas
Mostrando entradas con la etiqueta ajax. Mostrar todas las entradas

domingo, 29 de septiembre de 2013

jQuery Autocomplete en Django

Hola todos, esta vez vamos hacer algo muy útil cuando tenemos un campo estilo ForeignKey y se nos hace muy grande cuando tenemos muchos datos, como sabemos un campo ForeignKey nos hace un campo select en el formulario.

Tenemos el siguiente modelo:
class Persona(models.Model):
    cedula = models.CharField(unique=True, max_length=10)
    nombres = models.CharField(verbose_name='Nombres', max_length=60)
    apellidos = models.CharField(verbose_name='Apellidos', max_length=60)
class Proyecto(models.Model):
     titulo = models.CharField(max_length=200)
     autor = models.ForeignKey(Persona)
Ahora vamos a crear el forms.py, donde vamos a crear un campo adicional, que vamos a llamar persona_display:
class ProyectoForm(forms.ModelForm):
     persona_display = forms.CharField(max_length=100, help_text='tipee Cedula, Nombre o Apellido') 
     class_Meta:
          model = Proyecto
          fields=('titulo', 'persona_display', 'autor',) 
     def __init__(self, *args, **kwargs):
          super(ProyectoForm, self).__init__(*args, **kwargs)
          self.field['persona_display'].label = "Agrege el Autor"
          self.fields['autor'].widget = forms.HiddenInput()
¿Qué hemos hecho hasta aquí? 

Primero creamos nuestro formulario donde agregamos un campo adicional llamado persona_display, en el constructor de la clase hemos dado algunas características al campo persona lo hemos ocultado y le hemos agregado una etiqueta al nuevo campo persona_display

Ahora creamos nuestra url en urls.py:
url(r'^persona/autocomplete/$', 'persona_auto_complete', name='persona_auto_complete'),
Ahora la vista en views.py:
 def persona_auto_complete(request):
q = request.REQUEST['term']
if q:
qset = (
Q(cedula__istartswith=q) |
Q(nombres__icontains=q) |
Q(apellidos__icontains=q)
)
personas = Persona.objects.filter(qset).distinct()
else:
personas = []
personas_list = []
for p in personas:
value = '%s, (%s, %s)' % (p.cedula, p.nombres, p.apellidos)
p_dict = {'id': p.id, 'label': value, 'value': value}
personas_list.append(p_dict)
return HttpResponse(simplejson.dumps(personas_list))
Ahora podemos probar lo que hemos hecho, escribiendo en nuestro navegador:
http://localhost:8000/persona/autocomplete/?term=an
En este caso estamos buscando las personas que contengan en el nombre o apellido las letras "an" y nos mostrara un resultado como este:

[{"id": 3, "value": "1234567, (Ana Cecilia, La Cruz)", "label": "1234567, (Ana Cecilia, La Cruz)"}]

Si tenemos este resultado, ya podemos ahora agregar el código JQuery del plugin AutoComplete en nuestro template:

Recuerde que debe agregar los css del Jquery:
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css">
el formulario:
<form action="" method="post">{% csrf_token %}
<div class="forms">
    {{ form }}
    <input type="submit" name="submit" value="Salvar" />
</div>
</form>
Y ahora el JQuery y JQuery UI con el script de que hace accionar nuestro autocomplete:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script>
       $( document ).ready( function() {
        $("#id_persona_display").autocomplete({
        source: "{%  url 'persona_auto_complete' %}",
        dataType: "jsonp",
        selectFirst: true,
        minLength: 2,
        select: function(event,ui) {
        $("#id_autor").val(ui.item.id)
        }
        });
       });
</script>
Explicando un poco, estamos activando el auto complete en el campo que creamos en el form.py llamado persona_display, llamamos la url del autocomplete en la vista y le decimos por el parámetro minLength que empiece a buscar a partir del segundo carácter y al escoger le agregamos el id al campo autor, para que no nos de error, ya que es un campo requerido por ser clave.

Este es un ejemplo de como nos quedara el autocomplete,


Y eso es todo, espero que les sirva y lo pongan en practica en sus proyectos. Espero sus comentarios. Hasta la próxima.

martes, 17 de septiembre de 2013

Chequear disponibilidad de Campo Clave en Django 1.5

Hoy vamos a hacer algo para validar un campo en un  formulario, cuando le quitamos el foco al campo, este revisara en la base de datos, si ya existe, y no al final al hacer el submit. Esto es útil, para verificar si esta tomado el nombre de usuario, en caso de registro de usuarios, así como saber si el numero de identificación o cédula ya existe, entre otros.

Empecemos:

primero creamos nuestra url en urls.py
url(regex=r'^check_cedula/(?P<cedula>\d+)/$',
view=CedulaCheck.as_view(),
name='check_cedula'
),
Ahora nos vamos a nuestra vista views.py:
class CedulaCheck(TemplateView): 
def dispatch(self, *args, **kwargs):
self.cedula = self.kwargs['cedula']
return super(CedulaCheck, self).dispatch(*args, **kwargs) 
def get(self, request, *args, **kwargs):
if Persona.objects.filter(cedula__iexact=self.cedula):
return HttpResponse(False)
else:
return HttpResponse(True)
ya con esto podemos probar nuestra url con un numero de cédula y nos devolverá si existe o no
http://localhost:8000/check_cedula/12345678/
Ahora nos vamos a poner en acción nuestra API  recién creada con un formulario, primero creamos nuestra clase en views.py:
class PersonaCreateView(CreateView):
model = Persona
template_name = 'home/add_persona.html'
En nuestro html, nos vamos al campo que vamos a validar, es de notar que hice mi formulario a mano, no usando la plantilla de Django para crear los campos:
<div class="control-group">
<label for="cedula" class="control-label">
Cedula:
</label>
<div class="controls">
<input name="cedula" type="text" value="" id="cedula">
<span class="help-inline" id="idval">  Escriba su Cedula de Identidad</span>
</div>
</div>
y le agregamos el siguiente código jquery
<script>
function CheckId() {
$.get('/check_cedula/'+escape($('#cedula').val())+'/',
function(data){
if(data == "True"){
$('#idval').html("<i class='icon-ok'></i> Cedula disponible");
} else {
$('#idval').html("<i class='icon-remove'></i> Cedula existe");
}
});
}
function onChange(){
$("#cedula").change( function() {CheckId()});
}
$(document).ready(onChange);
</script> 
 Y listo, cuando coloquemos una cédula que ya existe, al dejar el foco del campo, nos dará una advertencia que ya existe y así no tenemos que escribir todos los campos y darle submit para que nos de el error.

Hasta la proxima