2016-07-14 83 views
1

圍繞這個主題有幾個問題,但沒有一個我發現適合我想要做的。我希望能夠將文件上傳到模型並使用模型實例屬性(如pk)將該文件保存在一個不錯的位置。我知道這個東西在model.save()之後被設置,所以我需要寫一個自定義的保存來做到這一點,但我無法弄清楚。以下是我有:Django FileField在上傳後移動文件

class UploadModel(models.Model): 
    image = models.ImageField(upload_to='uploads') 

    def save(self, *args, **kwargs): 

     # Call standard save 
     super(UploadModel, self).save(*args, **kwargs) 

     if 'uploads' in self.image.path: 

      initial_path = self.image.path 

      # New path in the form eg '/images/uploadmodel/1/image.jpg' 
      new_path = os.path.join(settings.MEDIA_ROOT, 'images', 
       self._meta.model_name, self.pk, os.path.basename(initial_path)) 

      # Create dir if necessary and move file 
      if not os.path.exists(os.path.dirname(new_path)): 
       makedirs(os.path.dirname(new_path)) 

      os.rename(initial_path, new_path) 

      # Do something here to save the new file to the image field 

      # Save changes 
      super(UploadModel, self).save(*args, **kwargs) 

我有什麼做的image領域得到它引用這個新文件的位置,並設置都喜歡image.pathimage.nameimage.url等有用的屬性呢?

docs說,以上是我應該需要做的,但這只是導致image字段指向一個不存在的文件。我查看了this相關問題,並嘗試了其中一個答案中提到的snippet,但我還沒有找到解決方案。

回答

0

經過大量的搜索找出this舊的文檔票據,有一個很好的解釋,我想通了。

class UploadModel(models.Model): 
    image = models.ImageField(upload_to='uploads') 

    def save(self, *args, **kwargs): 

     # Call standard save 
     super(UploadModel, self).save(*args, **kwargs) 

     if 'uploads' in self.image.path: 

      initial_path = self.image.path 

      # New path in the form eg '/images/uploadmodel/1/image.jpg' 
      new_name = '/'.join(['images', self._meta.model_name, str(self.id), 
       path.basename(initial_path)]) 
      new_path = os.path.join(settings.MEDIA_ROOT, 'images', 
      self._meta.model_name, self.pk, os.path.basename(initial_path)) 

      # Create dir if necessary and move file 
      if not os.path.exists(os.path.dirname(new_path)): 
       makedirs(os.path.dirname(new_path)) 

      os.rename(initial_path, new_path) 

      # Update the image_file field 
      self.image_file.name = new_name 

      # Save changes 
      super(UploadModel, self).save(*args, **kwargs) 

現在我讀的docs for this它看起來完全明顯:)但我覺得解釋可以做更多的描述。希望這會節省一些時間!

+0

根據https://docs.djangoproject.com/en/2.0/ref/models/fields/#django.db.models.FileField.upload_to,您應該只傳遞一個可調用的'upload_to =' – janek37