我有一个图片网址,我想在保存对象时从中设置一个ProcessedImageField属性。到目前为止,我已经得到了这个:
class Video(Media):
url = models.URLField('url', max_length=256, default='')
embed_url = models.URLField('embed url', max_length=256, default='')
thumbnail = ProcessedImageField(upload_to='uploads',
processors=[ResizeToFit(width=1024, height=1024, upscale=False)],
format='JPEG',
options={'quality': 75})
def save(self, *args, **kwargs):
from django.core.files.temp import NamedTemporaryFile
import shutil
import requests
import re
params = {
'url': self.url,
'autoplay': 1,
'format': 'json',
}
try:
data = requests.get('http://www.youtube.com/oembed', params=params).json()
embed_url = re.search('src=[\'"]([^\'"]*)[\'"]', data['html']).group(1)
thumbnail_url = data['thumbnail_url']
except:
pass
response = requests.get(thumbnail_url, stream=True)
img_temp = NamedTemporaryFile(delete=True)
shutil.copyfileobj(response.raw, img_temp)
# now image data are in img_temp, how to pass that to ProcessedImageField?
super(Video, self).save(*args, **kwargs)
答案 0 :(得分:1)
您应该能够在那时直接保存到该属性。
self.thumbnail.save("filename.ext", img_temp)
答案 1 :(得分:0)
这是我的结果代码(没有错误处理)。最后,我通过避免使用临时文件并使用ContentFile以更简单的方式进行了操作。
class Video(Media):
url = models.URLField('url', max_length=256, default='')
embed_url = models.URLField('embed url', max_length=256, default='')
author = models.CharField('author', max_length=64, default='', blank=True)
thumbnail = ProcessedImageField(upload_to='uploads',
processors=[ResizeToFit(width=1024, height=1024, upscale=False)],
format='JPEG',
options={'quality': 75})
def save(self, *args, **kwargs):
from django.core.files.base import ContentFile
import requests
import re
params = {
'url': self.url,
'format': 'json',
}
data = requests.get('http://www.youtube.com/oembed', params=params).json()
embed_url = re.search('src=[\'"]([^\'"]*)[\'"]', data['html']).group(1)
thumbnail_url = data['thumbnail_url']
author = data['author_name']
title = data['title']
image_data = requests.get(thumbnail_url, stream=True).raw.data
self.thumbnail.save(title, ContentFile(image_data), save=False)
self.embed_url = embed_url
self.author = author
self.title = title
super(Video, self).save(*args, **kwargs)
答案 2 :(得分:0)
好的,我已经用Python 3的代码结束了:) 它有内置的重试,它们之间有超时和支持下载大文件
def save_image_from_url(self, image_url):
s = requests.Session()
retries = Retry(total=5,
backoff_factor=0.1,
status_forcelist=[500, 502, 503, 504])
s.mount('https://', HTTPAdapter(max_retries=retries))
response = s.get(image_url, stream=True, timeout=9)
# here just use whatever name you want, I've just retrieve the path from my custom field
folder_name = Artist.image.field.upload_to.sub_path
random_name = uuid.uuid4().hex + ".png"
# creating folder if it doen't exist
try:
os.makedirs(os.path.join(settings.MEDIA_ROOT, folder_name))
except OSError as e:
if e.errno != errno.EEXIST:
raise
# loading image to tmp location and saving it, it's for large files because we can't handle them in memory
tmp = tempfile.NamedTemporaryFile(delete=True)
try:
tmp.write(response.raw.read())
with open(tmp.name, 'rb') as f:
self.image.save(random_name, f)
finally:
tmp.close()
self.image
为ProcessedImageField