我正在使用Django + DRF允许上传/保留/提供用户上传的资产文件。我需要让用户稍后下载上传的资产。上传文件后,我需要md5-hash其真实名称,并将其以文件名作为哈希值保存到文件系统中。然后,当用户要在FE上下载/查看它时,说他上载了文件'cute_cat.jpg',我希望他得到的文件名为'cute_cat.jpg',而不是3c808e77fc1b0aee4435533690be458d(名称是一个问题,另一个是问题一种是浏览器将不带扩展名的文件作为应用程序/八位字节流提供,我希望它将“ .jpg”(最初)文件呈现为图像)
我觉得我需要在HTTP标头中插入'Content-Disposition:附件; 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视图中没有任何内容。
非常感谢。
答案 0 :(得分:0)
首先,您需要了解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
上面的代码未经测试,但概念仍然存在。 如果您有任何疑问,请告诉我。