2016-05-05 18 views
0

根據文件擴展名,我希望文件存儲在特定的AWS存儲桶中。我嘗試將一個函數傳遞給storage選項,類似於upload_to是如何動態定義的。如何動態選擇models.FileField的存儲選項?

但是,這並沒有給出預期的結果。在我的模板中,當我嘗試href到document.docfile.url時,鏈接不起作用。

在外殼檢查,出現這種情況

Document.objects.all()[0].docfile.storage.bucket 
<Bucket: <function aws_bucket at 0x110672050>> 

Document.objects.all()[0].docfile.storage.bucket_name 
<function myproject.myapp.models.aws_bucket> 

期望的行爲將

Document.objects.all()[0].docfile.storage.bucket_name 
'asynch-uploader-txt' 
Document.objects.all()[0].docfile.storage.bucket  
<Bucket: asynch-uploader-txt> 

這是我models.py文件:

# -*- coding: utf-8 -*- 
from django.db import models 
from storages.backends.s3boto import S3BotoStorage 

def upload_file_to(instance, filename): 
    import os 
    from django.utils.timezone import now 
    filename_base, filename_ext = os.path.splitext(filename) 
    return 'files/%s_%s%s' % (
     filename_base, 
     now().strftime("%Y%m%d%H%M%S"), 
     filename_ext.lower(), 
    ) 

def aws_bucket(instance, filename): 
    import os 
    filename_base, filename_ext = os.path.splitext(filename) 
    return 'asynch-uploader-%s' %(filename_ext[1:]) 

class Document(models.Model): 
    docfile = models.FileField(upload_to=upload_file_to,storage=S3BotoStorage(bucket=aws_bucket)) 

爲什麼aws_bucket越來越作爲一個函數傳遞而不是一個字符串,方式upload_file_to是?我該如何糾正它?

回答

0

對於你想要做的事情,你可能更適合做一個自定義的存儲後端,並重寫S3BotoStorage的各個位。 特別是如果你讓bucket_name屬性,你應該能夠得到你想要的行爲。

編輯:

要展開對了一下,sourceS3BotoStorage.__init__bucket作爲可選參數。此外,bucket在課堂上使用時爲@param,因此很容易覆蓋。下面的代碼是未經測試的,但應該足以給你一個出發點

class MyS3BotoStorage(S3BotoStorage): 
    @property 
    def bucket(self): 
     if self._filename.endswith('.jpg'): 
      return self._get_or_create_bucket('SomeBucketName') 
     else: 
      return self._get_or_create_bucket('SomeSaneDefaultBucket') 

    def _save(self, name, content): 
     # This part might need some work to normalize the name and all... 
     self._filename = name 
     return super(MyS3BotoStorage, self)._save(name, content) 
+0

我不知道這是如何工作的。我需要在運行時通過文件名的擴展名來決定存儲區。如果我創建一個從S3BotoStorage繼承的新類,我不會被要求選擇一個固定的桶,或者遇到同樣的問題嗎? – thatharmansingh

+0

我沒有[this](http://pastebin.com/raw/GQJ6ad72),但存在同樣的問題,即docfile.bucket被賦予一個函數而不是字符串值,稍後訪問docfile.url會給出一個錯誤, 「不能連接str和函數」。 – thatharmansingh

+0

從我所看到的源代碼中,不需要在初始化時選擇它。如果你重寫bucket屬性,那麼你可以訪問所有的實例變量。我想你可以在那個時候訪問文件名,這將允許你正確計算你想要使用的存儲桶。以哪種方式查看S3BotoStorage源代碼。你不應該覆蓋太多的方法。 – Paul