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):¿Qué hemos hecho hasta aquí?
super(ProyectoForm, self).__init__(*args, **kwargs)
self.field['persona_display'].label = "Agrege el Autor"
self.fields['autor'].widget = forms.HiddenInput()
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):Ahora podemos probar lo que hemos hecho, escribiendo en nuestro navegador:
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))
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 %}Y ahora el JQuery y JQuery UI con el script de que hace accionar nuestro autocomplete:
<div class="forms">
{{ form }}
<input type="submit" name="submit" value="Salvar" />
</div>
</form>
<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.