将具有特定目录结构的图像文件上传到amazon s3 django

时间:2013-11-23 12:29:08

标签: django amazon-s3 image-uploading django-models

我有一个django模型,通过根据模型名称创建一些文件夹结构将文件上传到本地文件夹

utils.py

def asset_upload(instance, filename):
    ctype = ContentType.objects.get_for_model(instance)
    model = ctype.model
    app = ctype.app_label    

    if model == 'product':
        # Assets for a Product
        user_id = instance.user.fs_uid
        product_id = instance.id
        output = 'user%s/product%s/assets/%s' % (user_id, product_id, filename)

    elif model == 'category':
        # Assets for a Product
        user_id = instance.user.fs_uid
        product_id = instance.id
        output = 'user%s/category%s/assets/%s' % (user_id, product_id, filename)

    else:
        raise NotImplementedError("Unsupported model for Image Upload")

    return output

models.py

class Product(models.Model):
    name = models.CharField(max_length = 36)
    description = models.TextField(max_length = 2000)
    created = models.DateTimeField(auto_now_add = True)
    updated = models.DateTimeField(auto_now = True)
    picture = models.ImageField(upload_to = utils.asset_upload, null = True, max_length = 250)
    picture.allow_tags = True

forms.py

class ProductForm(ModelForm):
    class Meta:
        model = Product

views.py

def product_creation(request):
    product_form = ProductForm()
    if request.method == 'POST':
        product_form = ProductForm(request.POST,request.FILES)
        if product_form.is_valid():
            obj = product_form.save(commit=False)
            obj........ = ....
            obj.save()
            return redirect(reverse('product_detail', args=[obj.id]))
    return render_to_response('products/product.html',
                                    { 'product_form':product_form,},
                                    context_instance = RequestContext(request))  

因此,从上面的代码中,我可以将图像成功上传到media文件夹,如

/media/user235/product269/assets/buscuits_butter.png
/media/user235/product269/assets/choclate_pie.png

但现在我想将上面的图像存储到Amazon s3而不是我的本地文件系统

所以通过谷歌搜索我发现了一些代码,如here

def store_in_s3(filename, content):
    conn = S3Connection(settings.ACCESS_KEY, settings.PASS_KEY)
    b = conn.create_bucket("bucket_name")
    mime = mimetypes.guess_type(filename)[0]
    k = Key(b)
    k.key = filename
    k.set_metadata("Content-Type", mime)
    k.set_contents_from_string(content)
    k.set_acl("public-read")

所以从上面的函数中,如果我发送我的文件路径和内容,那么我希望图像将保存到亚马逊s3(通过提供所有凭据)

但是我confused关于如何在这个函数中实现/发送文件(带有一些目录路径)。

我尝试在模型中设置upload_to = None但遇到错误

product: "picture": FileFields require an "upload_to" attribute.

现在我们也知道,希望避免将文件保存到本地文件夹,并将其保存到亚马逊桶中

所以任何人都可以告诉我如何hook/re arrange我的上述代码上传图像的文件目录结构我根据上面的模型结构生成

1 个答案:

答案 0 :(得分:0)

看看Django的File Storage API,尤其是S3 Storage

我不会将函数作为upload_to关键字传递。您可以考虑创建继承ImageField并编写自己的命名方法。