2013-10-15 73 views
1

我有一个图像URL,我想在保存对象时设置一个ProcessedImageField属性。到目前为止,我已经得到了这个:django imagekit:从图像中设置ProcessedImageField url

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) 

回答

1

你应该能够直接保存到那个属性。

self.thumbnail.save("filename.ext", img_temp) 
+0

你是对的。有用:)。 – clime

+0

需要将save = False作为第三个参数。否则,在我的情况下,它会在一个递归循环中结束。 – clime

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) 
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.imageProcessedImageField