6
class Item(models.Model):
    name = models.CharField(max_length = 200)
    image = models.ImageField(upload_to = 'read', blank=True)
    creative_url = models.CharField(max_length = 200)
    description = RichTextField()

    def save(self, *args, **kwargs):
        content = urllib2.urlopen(self.creative_url).read()
        self.image.save("test.jpg", File(content))
        super(Item, self).save(*args, **kwargs)

Gives exception: 'str' object has no attribute 'name'

I was trying to follow this answer (http://stackoverflow.com/questions/1393202/django-add-image-in-an-imagefield-from-image-url) But it did not help to get rid of the exception.


AttributeError at /admin/collection/item/1/ 'str' object has no attribute 'name' Request Method:    POST Request
URL:    http://127.0.0.1:8000/admin/collection/item/1/ Django
Version:    1.2.5 Exception Type:   AttributeError Exception Value:  'str'
object has no attribute 'name' Exception
Location:   D:\FF\django\core\files\base.py in _get_size, line 39 Python
Executable: C:\Python27\python.exe Python Version:  2.7.2 Python
Path:   ['D:\\FF',
'C:\\Python27\\lib\\site-packages\\django_social_auth-0.6.7-py2.7.egg',
'C:\\Python27\\lib\\site-packages\\python_openid-2.2.5-py2.7.egg',
'C:\\Python27\\lib\\site-packages\\oauth2-1.5.211-py2.7.egg',
'C:\\Python27\\lib\\site-packages\\httplib2-0.7.4-py2.7.egg',
'C:\\Python27\\lib\\site-packages\\selenium-2.20.0-py2.7.egg',
'C:\\Python27\\lib\\site-packages\\ipython-0.12-py2.7.egg',
'C:\\Python27\\lib\\site-packages\\django_localeurl-1.5-py2.7.egg',
'C:\\Python27\\lib\\site-packages\\pil-1.1.7-py2.7-win32.egg',
'C:\\Python27\\lib\\site-packages\\pip-1.1-py2.7.egg',
'C:\\Windows\\system32\\python27.zip', 'C:\\Python27\\DLLs',
'C:\\Python27\\lib', 'C:\\Python27\\lib\\plat-win',
'C:\\Python27\\lib\\lib-tk', 'C:\\Python27',
'C:\\Python27\\lib\\site-packages',
'c:\\python27\\lib\\site-packages'] Server time:    Tue, 24 Apr 2012
14:19:00 +0300
2
  • 1
    Show the real exception and traceback, please. Commented Apr 24, 2012 at 11:03
  • Have you posted your entire model? It sounds like this isn't related directly to the image saving. Is there a unicode method on your model? Commented Apr 24, 2012 at 12:11

3 Answers 3

8

Instead of File, you need to use django.core.files.base.ContentFile

self.image.save("test.jpg", ContentFile(content), save=False)

File accepts file object or StringIO object having size property or you need to manually set size property of a File or ImageFile to make it working w/ StringIO:

s = StringIO()
s.write(urllib2.urlopen(self.creative_url).read())
s.size = s.tell()
self.image.save('test.jpg', File(s), save=False)

Also, please note the save=False inside self.image.save: by default, save=True, this will cause the instance, which contains the image field, to be saved. Thus the save logic in your code might encounter an infinite loop and reach maximum recursion depth.

Sign up to request clarification or add additional context in comments.

3 Comments

Love your answer because I was in that inf loop :)
Great answer! Although I had to remove save=False since it caused the image to not save into the model field, but without it it works fine (perhaps because I used a model method and didn't override in .save()?)
@Hybrid Yeah, very likely.
6

Try something like:

(As supposed at: Programmatically saving image to Django ImageField)

from django.db import models
from django.core.files.base import ContentFile
import urllib2
from PIL import Image
from StringIO import StringIO

class Item(models.Model):
    name = models.CharField(max_length=200)
    image = models.ImageField(upload_to='read', blank=True)
    creative_url = models.URLField(max_length=200)

    class Meta:
        verbose_name = "Item"
        verbose_name_plural = "Items"

    def download_image(self, url):
        input_file = StringIO(urllib2.urlopen(url).read())
        output_file = StringIO()
        img = Image.open(input_file)
        if img.mode != "RGB":
            img = img.convert("RGB")
        img.save(output_file, "JPEG")
        self.image.save(self.name+".jpg", ContentFile(output_file.getvalue()), save=False)

    def save(self, *args, **kwargs):
        self.download_image(self.creative_url)
        super(Item, self).save(*args, **kwargs)

Comments

2

solution using requests

from django.core.files.base import ContentFile
from requests import request, HTTPError

def save(self, *args, **kwargs):
    try:
        data = request('GET', self.creative_url,)
        data.raise_for_status()
        self.image.save('fname.jpg', ContentFile(data.content),save=False)
    except HTTPError:
        pass
    super(Item, self).save(*args, **kwargs)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.