Django save image from url and connect with ImageField
Asked Answered
M

4

37

I have in models.py:

class Item(models.Model):
    image_file = models.ImageField(upload_to='images')
    image_url = models.URLField()

I want django automatically download and locally save image from image_url and "connect" it with image_file

How it should act:

  1. I Paste https://docs.djangoproject.com/s/img/site/hdr_logo.gif into image_url field in admin
  2. Click "save"
  3. In templates write <img src="{{ item.image_file.url }}">. It shows image from my server, not djangoproject.com

What I've tried:

I've overwritten save method of Item class. I saved image locally via urllib, but I am stuck on connecting this saved image with image_file field

Medulla answered 5/5, 2013 at 3:55 Comment(0)
G
51
from django.core.files import File
import os

class Item(models.Model):
    image_file = models.ImageField(upload_to='images')
    image_url = models.URLField()

...

def get_remote_image(self):
    if self.image_url and not self.image_file:
        result = urllib.urlretrieve(self.image_url)
        self.image_file.save(
                os.path.basename(self.image_url),
                File(open(result[0]))
                )
        self.save()

You can override the default save() method to automatically invoke get_remote_image().

See: https://docs.djangoproject.com/en/dev/topics/db/models/#overriding-model-methods

Geese answered 5/5, 2013 at 9:24 Comment(3)
How do you set the image's file name?Lamentation
Python3 update: #17961442Parterre
I am getting AttributeError: 'NoneType' object has no attribute 'save' when doing article.featured_image.save(name, ContentFile(response.content), save=True). have any idea why ? article is instance .Miyasawa
G
14
from django.db import models
from django.core.files import File
from urllib.request import urlopen
from tempfile import NamedTemporaryFile

class Item(models.Model):
    image_file = models.ImageField(upload_to='images')
    image_url = models.URLField()

...

def get_remote_image(self):
    if self.image_url and not self.image_file:
        img_temp = NamedTemporaryFile(delete=True)
        img_temp.write(urlopen(self.image_url).read())
        img_temp.flush()
        self.image_file.save(f"image_{self.pk}", File(img_temp))
    self.save()

This solution avoid any utf-8 errors received during url process.

It works only with python 3.6+ because the f string.

Check this link: https://twigstechtips.blogspot.com/2012/04/django-programmatically-saving-image.html

Gibe answered 7/10, 2018 at 16:1 Comment(0)
C
11

For python3

from django.core.files import File
from urllib import request
import os

class Item(models.Model):
    image_file = models.ImageField(upload_to='images')
    image_url = models.URLField()

...

def get_remote_image(self):
    if self.image_url and not self.image_file:
        result = request.urlretrieve(self.image_url)
        self.image_file.save(
                os.path.basename(self.image_url),
                File(open(result[0], 'rb'))
                )
        self.save()

from here: https://mcmap.net/q/203011/-attributeerror-39-module-39-object-has-no-attribute-39-urlretrieve-39

Cuthburt answered 27/12, 2017 at 23:17 Comment(1)
This seems to work for me where others don't, when uploading to my Backblaze B2 storage bucket.Herbst
H
7

Python3

from django.db import models
from django.core.files import File
from urllib.request import urlopen
from tempfile import NamedTemporaryFile

class Item(models.Model):
    image_file = models.ImageField(upload_to='images')
    image_url = models.URLField()

    def save(self, *args, **kwargs):
        if self.image_url and not self.image_file:
            img_temp = NamedTemporaryFile(delete=True)
            img_temp.write(urlopen(self.image_url).read())
            img_temp.flush()
            self.image_file.save(f"image_{self.pk}", File(img_temp))
        super(Item, self).save(*args, **kwargs)

It`s similar but with automated save 'image_file', when add 'image_url'

Hoo answered 16/4, 2019 at 19:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.