django - 在 FE 上下载/引用期间是否可以交换 FileField 的文件名?
问题描述
我正在使用 Django+DRF 来允许上传/保留/服务用户上传的资产文件。我需要让用户稍后下载上传的资产。在文件上传时,我需要对其真实名称进行 md5 哈希处理,并将其保存到文件系统中,并以该哈希作为文件名。然后,当用户想在 FE 上下载/查看它时,假设他上传了一个文件 'cute_cat.jpg',我希望他得到名为 'cute_cat.jpg' 的文件而不是 3c808e77fc1b0aee4435533690be458d (名称是一个问题,另一个一种是浏览器将不带扩展名的文件作为应用程序/八位字节流提供,我希望它将“.jpg”(最初)文件呈现为图像)
我觉得我需要用 'Content-Disposition: attachment; 注入一个 HTTP 标头;filename=cute_cat.jpg'(我将真实文件名存储在 DB 中)在通往 DRF 的 Response() 途中的某个地方,但我不确定在什么时候我要这样做,即使它是可能的......我尝试了很多东西,主要是为序列化程序实现自定义字段并在那里注入一个自定义 URL,但显然这不是办法,因为没有地方可以将标头注入到文本 URL 并且尝试输出没有意义API 视图中带有标头的请求对象...
这是我的模型:
def get_full_path(instance, filename):
return '/'.join([
instance.user.name,
hashlib.md5(filename.encode()).hexdigest()
])
class CustomAsset(models.Model):
file = models.FileField(blank=False, null=False, upload_to=get_full_path)
real_file_name = models.CharField(max_length=255, blank=False, null=False)
user = models.ForeignKey(...)
序列化程序/API 视图中没有任何内容被覆盖。
提前非常感谢。
解决方案
首先您需要了解API,您可以返回的只是URL。
现在,处理文件格式和内容类型管理是浏览器的职责。您需要在这里做的是通过您的应用程序控制器管理文件。当您返回网址时,您会返回类似的网址。
http://example.com/file/<md5>
访问时,此 url 通过控制器为文件提供服务,并带有修改的内容处置标头,并将文件作为响应返回。
一个简单的例子看起来像。
在您的 urls.py 中,添加一条新路线。
url(r'^file/(?P<identifier>[\w\d\-_]+)$', custom_file_server, name="custom_file_server"),
然后根据您的需要提供文件。一个简单的例子就是这样。
def custom_file_server(request, identifier):
## Get the file name from db by querying from identifier
file_name = "abc.jpg"
absolute_file_path = os.path.join(settings.BASE_DIR, "media/"+identifier)
response = FileResponse(open(absolute_file_path, 'rb'))
response['Content-Disposition'] = "attachment; filename={}".format(file_name)
response['Content-Type'] = 'image/jpeg'
return response
上面的代码未经测试,但概念仍然如此。如果您有任何问题,请告诉我。
推荐阅读
- assembly - 三个数字的玛丽模拟器乘法
- prism - 模块独有的 ViewModelLocator 约定
- javascript - 基于列数据的 Ag-grid 复选框渲染?
- r - 使用 stat_density_2d(geom = "polygon") 时无渲染
- c# - 以纯文本形式接收的 C# MailKit HTML 电子邮件
- html - 无法访问html表中的数组元素
- javascript - 记录函数名称而不输出其内容
- java - 类状态变化时的Java序列化和反序列化
- python-3.x - Python - 如何将实例变量设置为类变量列表中的数字
- python - 如何使用 F-score 作为误差函数来训练神经网络?