获取Django生成的多次上传文件的唯一名称

时间:2017-08-04 21:15:12

标签: python django django-rest-framework

我正在使用DRF后端上传文件。在我的具体情况下,我想要获取文件的名称,上传之后。原因是如果用户上传具有相同名称的文件,我仍然可以独立处理它。

views.py

class ImageUploaderView(viewsets.ModelViewSet):
    renderer_classes = [renderers.JSONRenderer]
    queryset = ImageUploader.objects.all()
    serializer_class = ImageUploaderSerializer
    parser_classes = (MultiPartParser,)

serializer.py

class ImageUploaderSerializer(serializers.ModelSerializer):
    class Meta:
        model = ImageUploader

models.py

class ImageUploader(models.Model):
    # name=models.ImageField(upload_to='media')
    name=models.FileField(upload_to='media')

我试图在模型定义之后放置信号和钩子,但我无法获得此文件名。有人可以轻松一点吗?

更新:让我详细说明我想要实现的目标:

  • User1命中端点" / api / calculate_interest_rate"这是渲染 通过前端React组件。 " calculate_interest_rate"是送达的 DRF,并允许用户上传CSV文件。这将存储为 " user1.csv",处理文件然后制表(由...呈现) 反应)。

  • 同时并且与User1并行,User2命中相同的端点" / api / calculate_interest_rate"和 他错误地将文件保存为" user1.csv",并将其上传到systemn。

所以我希望能够检测文件的两个名称以便处理它。通过使用相同的默认文件名(例如使用OverwriteStorage()技术),当两个或多个用户使用相同的文件名时,我可能会导致混乱。因此,我正在研究一种技术,它允许我按原样获取文件名,并立即处理它。

2 个答案:

答案 0 :(得分:1)

如何使用存储选项?

class OverwriteStorage(FileSystemStorage):
    def get_available_name(self, name, max_length=None):
        print("filename", name)
        #parts = name.split('.') you can separate name and extension.
        return super().get_available_name(name)

upload_image = models.ImageField(
    upload_to=[yourpath],
    default=[defaultname],
    storage=OverwriteStorage()
)

答案 1 :(得分:0)

我建议您遵循以下配置:

1。更改MEDIA_ROOT内的MEDIA_URLsettings.py内部文件

MEDIA_URL = '/media/'
MEDIA_ROOT = '/path/to/env/projectname/media'

2. 然后,我建议您将upload_to='media更改为upload_to='images/%Y/%m/%d,并将name的字段重命名为image。< / p>

class ImageUploader(models.Model):
    image = models.FileField(upload_to='images/%Y/%m/%d')
    # OR
    # image = models.ImageField(upload_to='images/%Y/%m/%d')
  

说明; 如果您遵循此配置,则可能会跟踪上传的图片,例如:/media/images/2017/01/29/yourimage.jpg。这是处理重复文件问题的一种方法。

3。但是如果您想多次上传文件而没有重复文件,可以使用deconstructible;

import os, time, uuid
from django.db import models
from django.utils.deconstruct import deconstructible


class ImageUploader(models.Model):

    @deconstructible
    class PathAndRename(object):

        def __init__(self, sub_path):
            self.path = sub_path

        def __call__(self, instance, filename):
            # eg: filename = 'my uploaded file.jpg'
            ext = filename.split('.')[-1]  #eg: '.jpg'
            uid = uuid.uuid4().hex[:10]    #eg: '567ae32f97'

            # eg: 'my-uploaded-file'
            new_name = '-'.join(filename.replace('.%s' % ext, '').split())

            # eg: 'my-uploaded-file_64c942aa64.jpg'
            renamed_filename = '%(new_name)s_%(uid)s.%(ext)s' % {'new_name': new_name, 'uid': uid, 'ext': ext}

            # eg: 'images/2017/01/29/my-uploaded-file_64c942aa64.jpg'
            return os.path.join(self.path, renamed_filename)

    image_path = time.strftime('images/%Y/%m/%d')
    image = models.ImageField(upload_to=PathAndRename(self.image_path))