template serve muestra mostrar img imagenes example python django urllib django-models

python - serve - mostrar imagenes django



Django: agregar imagen en un campo de imagen desde la url de la imagen (7)

por favor discúlpeme por mi feo inglés ;-)

Imagina este modelo muy simple:

class Photo(models.Model): image = models.ImageField(''Label'', upload_to=''path/'')

Me gustaría crear una foto a partir de una URL de imagen (es decir, no a mano en el sitio de administración de django).

Creo que necesito hacer algo como esto:

from myapp.models import Photo import urllib img_url = ''http://www.site.com/image.jpg'' img = urllib.urlopen(img_url) # Here I need to retrieve the image (as the same way that if I put it in an input from admin site) photo = Photo.objects.create(image=image)

Espero haber explicado bien el problema, si no me lo dices.

Gracias :)

Editar:

Esto puede funcionar, pero no sé cómo convertir content a un archivo django:

from urlparse import urlparse import urllib2 from django.core.files import File photo = Photo() img_url = ''http://i.ytimg.com/vi/GPpN5YUNDeI/default.jpg'' name = urlparse(img_url).path.split(''/'')[-1] content = urllib2.urlopen(img_url).read() # problem: content must be an instance of File photo.image.save(name, content, save=True)


Acabo de crear http://www.djangosnippets.org/snippets/1890/ para este mismo problema. El código es similar a la respuesta sin contenido anterior, excepto que usa urllib2.urlopen porque urllib.urlretrieve no realiza ningún manejo de errores de manera predeterminada, por lo que es fácil obtener el contenido de una página 404/500 en lugar de lo que necesita. Puede crear la función de devolución de llamada y la subclase URLOpener personalizada, pero me resultó más fácil simplemente crear mi propio archivo temporal de esta manera:

from django.core.files import File from django.core.files.temp import NamedTemporaryFile img_temp = NamedTemporaryFile(delete=True) img_temp.write(urllib2.urlopen(url).read()) img_temp.flush() im.file.save(img_filename, File(img_temp))


Combinando lo que Chris Adams y Stan dijeron y actualizando las cosas para trabajar en Python 3, si instalas las Requests puedes hacer algo como esto:

from urllib.parse import urlparse import requests from django.core.files.base import ContentFile from myapp.models import Photo img_url = ''http://www.example.com/image.jpg'' name = urlparse(img_url).path.split(''/'')[-1] photo = Photo() # set any other fields, but don''t commit to DB (ie. don''t save()) response = requests.get(img_url) if response.status_code == 200: photo.image.save(name, ContentFile(response.content), save=True)

Documentos más relevantes en la documentación de Contenthange de Django y en el ejemplo de descarga de archivos de Solicitudes .


Lo hago de esta manera en Python 3, que debería funcionar con adaptaciones simples en Python 2. Esto se basa en mi conocimiento de que los archivos que estoy recuperando son pequeños. Si el tuyo no lo es, probablemente recomendaría escribir la respuesta en un archivo en lugar de almacenarla en la memoria.

Se necesita BytesIO porque Django llama a seek () en el objeto de archivo y las respuestas de urlopen no son compatibles con la búsqueda. Podría pasar el objeto bytes devuelto por read () al ContentFile de Django en su lugar.

from io import BytesIO from urllib.request import urlopen from django.core.files import File # url, filename, model_instance assumed to be provided response = urlopen(url) io = BytesIO(response.read()) model_instance.image_field.save(filename, File(io))


Si está utilizando la función de carga de archivos en su proyecto Django, primero debe instalar Pillow:

pip install pillow==2.6.1

Recuerde configurar la url para archivos multimedia en settings.py:

MEDIA_ROOT = ''media/''

Luego, en su models.py, agregue el siguiente campo de imagen:

userlogo = models.ImageField(upload_to="userlogo/", blank=True, null=True)

Después de escribir este código, migre el modelo usando:

python manage.py makemigrations python manage.py migrate

Ahora puede cargar archivos de imagen usando el campo de imagen. Los archivos de imagen se subirían al directorio YOUR_PROJECT_ROOT / media / userlogo. No es necesario crear la carpeta ''userlogo'' manualmente.


esta es la forma correcta y funcional

class Product(models.Model): upload_path = ''media/product'' image = models.ImageField(upload_to=upload_path, null=True, blank=True) image_url = models.URLField(null=True, blank=True) def save(self, *args, **kwargs): if self.image_url: import urllib, os from urlparse import urlparse filename = urlparse(self.image_url).path.split(''/'')[-1] urllib.urlretrieve(self.image_url, os.path.join(file_save_dir, filename)) self.image = os.path.join(upload_path, filename) self.image_url = '''' super(Product, self).save()


ImageField es solo una cadena, una ruta relativa a su configuración MEDIA_ROOT . Simplemente guarde el archivo (es posible que desee usar PIL para verificar que sea una imagen) y rellene el campo con su nombre de archivo.

Por lo tanto, difiere de su código en que necesita guardar la salida de su urllib.urlopen en el archivo (dentro de su ubicación de medios), calcular la ruta y guardarla en su modelo.


from myapp.models import Photo import urllib from urlparse import urlparse from django.core.files import File img_url = ''http://www.site.com/image.jpg'' photo = Photo() # set any other fields, but don''t commit to DB (ie. don''t save()) name = urlparse(img_url).path.split(''/'')[-1] content = urllib.urlretrieve(img_url) # See also: http://docs.djangoproject.com/en/dev/ref/files/file/ photo.image.save(name, File(open(content[0])), save=True)