Django Guardar imágenes (o blobs) desde la red


Debido a las consultas amplío el post anterior para aclarar un poco el proceso suponiendo que bajamos las imágenes desde un servidor sFTP, sólo hay que cambiar los parámetros de pycurl para operar con http, https, etc...

Primero bajamos la imagen a memoria con algún gestor (pycurl por ejemplo o urllib) y guardarlo en un cStringIO:


import pycurl, cStringIO

buf = cStringIO.StringIO()
url=('ftps://%s:990/%s' % (ip, fichero))
privatekey = '/home/sss/.ssh/id_rsa'
options = {
pycurl.USERPWD: 'xxxxx:xxxx',
pycurl.SSLKEYPASSWD: 'adfasdfasdfas',
pycurl.SSH_PRIVATE_KEYFILE: privatekey,
pycurl.SSH_PUBLIC_KEYFILE: privatekey + '.pub',
#pycurl.WRITEDATA: open('/dev/null', 'wb'),
pycurl.VERBOSE: 1,
pycurl.URL: url,
pycurl.HEADER: 1,
pycurl.NOBODY: 1,
pycurl.WRITEFUNCTION: buf.write,
pycurl.NOPROGRESS: 1,
pycurl.SSL_VERIFYPEER: 0,
pycurl.SSL_VERIFYHOST: 0,
}

gestor = pycurl.Curl()
try:
for (k, v) in options.items():
print k, v
gestor.setopt(k, v)
except Exception, msg:
logging.info('Error setopt %s' % msg)

gestor.perform()



Ahora ya tenemos la imagen en memoria (buf), vamos a grabarla (django la graba en disco y en la db solo se guarda el path), el único problema es que ImageField espera un campo file, pero lo solucionaremos con un workaround:

En tu modelo pones:

class Persona(models.Model):
.....
imagen=models.ImageField(upload_to=settings.PATH_FOTOS_CLIENTES, blank=True)


Donde settings.PATH_FOTOS_CLIENTES apunta a la ruta que cuelga de la ruta que tengas en settings.MEDIA_ROOT y tiene el formato siguiente o similar (en settings.py):


PATH_FOTOS_CLIENTES='clientes/%Y/%m/%d'


Ahora tenemos que pasar de la imagen que tienes cargada en memoria a un stream tipo 'file' para que pueda ser guardado por el modelo:


from django.core.files.uploadedfile import SimpleUploadedFile

foto = SimpleUploadedFile('imagencliente.jpg',
buf.getvalue(),
"image/jpeg")


y ya salvamos:

p=Persona( imagen=foto )
p.save()


Comentad si os surge alguna duda.
Saludos,
Pere Vilás.