Upload imagen con preview para Django.

Después de renegar un rato y gracias a la ayuda de la lista de Pyar especialmente de Alessandro Odetti.

Entendí como lograr un upload de una imagen con un form de Django que se vea decente y tenga un preview. En este post hago foco de como modificar el Template no en como recibir y procesar el form.

Así se ve normalmente el FileInput de Django.

Primero Arrancamos de un modelo en model.py:

class Teacher(models.Model):
headline = models.CharField(max_length=200) # este no lo usamos
photo = models.ImageField(null=True, blank=True)

Después el ModelForm en form.py

class TeacherForm(forms.ModelForm): 
class Meta:
model = Teacher
fields = (‘photo’, ‘headline’)

Por ultimo creamos una instancia con la view.py y la mandamos al template (no coloco todo el código para que sea mas simple de entender).

def teacherview(request):
teacherform = TeacherForm()
return render(request, "teacher.html", locals())

Ahora a lo mas interesante el template, para esto tome de un post de stackoverflow parte de html y un script de JS. Como todo sabemos los form de Dango son equivalentes a un label más un input. Entonces nosotros debemos logra un input como el del post de stackoverflow con un id y un class= “hide”.

Ya que no podemos modificar la variable simplemente tomamos el id con el que se identifica.

<form class=”m-t” role=”form” action=”/newteacher/{{user.pk}}” enctype=”multipart/form-data” method=”post”>
{% csrf_token %}
<div class=”col-md-6" align=”center”>

<p>Imagen de Perfil.</p>
<!--Este es el preview -->
<div class=”img-preview img-preview-sm”>
<img id=”blah” src=”/static/img/a2.jpg” alt=”your image” width=”100" height=”100" />
</div>
<!--Este es el boton de upload-->
<div class=”btn-group”>
<!--asociamos el for del label a la llamada del script de JS -->
<label title=”Subir Imagen” for=”id_{{teachform.photo.name}}” class=”btn btn-primary”>
<div style="display: none"> {{teachform.photo}} </div>
<!-- hacer style="display: none es equivalente a class="hide" "-->
Upload new image
</label>
</div>
<div class=”form-group”>
<p>Una Frase de cabecera.</p>
{{ teachform.headline}}
</div>
<button type="submit" class="btn btn-primary block full- width m-b">Cargar Perfil</button>

</div>
</form>

Ahora la magia de JS, es asociar el id con el que llama a la funcion con una variable de template de Django:

<script>
$(document).ready(function() {
  function readURL(input) {
    if (input.files && input.files[0]) {
var reader = new FileReader();
  reader.onload = function(e) {
$(‘#blah’).attr(‘src’, e.target.result);
}
  reader.readAsDataURL(input.files[0]);
}
}
// agregando id_{{variablename}} armo el id para que reconozca la función
$(“#id_{{teachform.photo.name}}”).change(function() {
readURL(this);
});
});
</script>

Con esto agregado a nuestro Boostrap vamos a tener un simple pero bonito form con preview de Imagen. Y quedando algo un poco mas bonito y funcional como:

Espero que les Sea Útil.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.