我有以下型号。
class Image(models.Model):
customer = models.ForeignKey(Customer, related_name='images')
image = models.ImageField(upload_to='/pictures/', verbose_name='Image')
每次用户添加新图片时,我都希望将其放在pictures/customer.id/custom_filename
下
当我使用本地文件系统时,这很容易。我使用了一个处理文件块上传的函数,并使用新名称并返回新路径。但现在我想用S3来存储我的文件。所以我使用的是django-storage。我做了以下测试:
testmodel
class TestModel(models.Model):
name = models.CharField(max_length=10)
logo = models.ImageField(upload_to='pictures/')
当我在我看来这样做时
def index(request):
form = TestModelForm(request.POST or None, request.FILES or None)
if request.method == 'POST':
if form.is_valid():
print 'posting form'
model = form.save(commit=False)
print model.name
print model.logo.url
model.save()
并在mybucket.s3.amazon.com/pictures/logoname.jpg
下按原样上传图片
但是,如果我通过某种方式更改文件名,如
def index(request):
form = TestModelForm(request.POST or None, request.FILES or None)
if request.method == 'POST':
if form.is_valid():
print 'posting form'
model = form.save(commit=False)
print model.name
filename = str(request.FILES['logo']).split('.')[0]
extension = str(request.FILES['logo']).split('.')[1]
path = '%d%d%d_%s_%d.%s' %(datetime.now().year, datetime.now().month, datetime.now().day, filename, models_no+1, extension)
model.logo = path
print model.logo.url
model.save()
我得到一个新的网址mybucket.s3.amazon.com/newlogoname.jpg
(正确,因为我没有在新路径中显示用户图片),但文件未上传。我必须手动使用boto吗?我想这是唯一的方法,因为每个客户(初始示例)的文件夹可能不存在并且需要创建。在每个模型的自定义位置/目录上传图像的正确方法是什么?
我试图直接调用默认存储将图像保存在我想要的位置但是没有工作
default_storage.save('pictures/one.jpg', ContentFile(request.FILES['logo']))
创建密钥(文件夹和文件)但图像为空。我认为以灵活的方式使用云存储非常困难:(
答案 0 :(得分:1)
您可以在模型定义中传递一个callable作为 upload_to 命名参数(因此您实际上不必在视图级别执行此操作)。为了说清楚,尝试做这样的事情:
class Image(models.Model):
customer = models.ForeignKey(Customer, related_name='images')
image = models.ImageField(upload_to=self.generate_upload_path, verbose_name='Image')
def generate_upload_path(self, filename):
return os.path.join('/pictures/'+str(self.customer.id), filename)