我正在使用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()技术),当两个或多个用户使用相同的文件名时,我可能会导致混乱。因此,我正在研究一种技术,它允许我按原样获取文件名,并立即处理它。
答案 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_URL
和settings.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))