【问题标题】:Changing save location of file for a model inside a view更改视图内模型的文件保存位置
【发布时间】:2014-05-14 21:32:08
【问题描述】:

我有以下型号。

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-storages。我做了以下测试:

测试模型

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()

我得到一个新的 url,它是 mybucket.s3.amazon.com/newlogoname.jpg(正确,因为我没有在新路径中使用图片)但文件没有上传。我必须使用 boto 手动完成吗?我想这是唯一的方法,因为每个客户的文件夹(初始示例)可能不存在并且需要创建。在每个模型的自定义位置/目录上传图片的正确方法是什么?

我尝试直接调用默认存储将图像保存在我想要的位置但没有工作

default_storage.save('pictures/one.jpg', ContentFile(request.FILES['logo']))

密钥已创建(文件夹和文件),但图像为空。我认为以灵活的方式使用云存储非常困难:(

【问题讨论】:

    标签: django amazon-web-services amazon-s3 boto


    【解决方案1】:

    您可以在模型定义中将可调用对象作为 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)
    

    【讨论】:

      猜你喜欢
      • 2010-11-20
      • 2021-04-18
      • 1970-01-01
      • 2017-04-17
      • 2020-09-19
      • 1970-01-01
      • 2011-07-18
      • 2011-02-13
      • 2014-07-02
      相关资源
      最近更新 更多