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
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.
(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)
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With