【问题标题】:Is it possible to swap FileField's filename during download/referencing on FE?在 FE 上下载/引用期间是否可以交换 FileField 的文件名?
【发布时间】:2019-07-03 10:22:12
【问题描述】:

我正在使用 Django+DRF 来允许上传/保留/服务用户上传的资产文件。我需要让用户稍后下载上传的资产。在文件上传时,我需要对其真实名称进行 md5-hash 并将其保存到文件系统中,并以该哈希作为文件名。然后,当用户想在 FE 上下载/查看它时,假设他上传了一个文件“cute_cat.jpg”,我希望他获取名为“cute_cat.jpg”的文件而不是 3c808e77fc1b0aee4435533690be458d(名称是一个问题,另一个一种是浏览器将不带扩展名的文件作为 application/octet-stream 提供,我希望它将“.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 视图中没有任何内容被覆盖。

非常感谢。

【问题讨论】:

  • 这里的 FE 是什么?
  • FE=前端,BE=后端

标签: django django-rest-framework


【解决方案1】:

首先您需要了解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

上面的代码没有经过测试,但概念仍然如此。 如果您有任何问题,请告诉我。

【讨论】:

  • 非常感谢,我最终在我的 API 视图中覆盖了检索方法,但代码基本相同,我也使用了 FileResponse。这当然不是理想的结果,但我想没有办法像我想要的那样,哦,好吧,现在就足够了
猜你喜欢
  • 1970-01-01
  • 2019-10-31
  • 1970-01-01
  • 2013-07-15
  • 1970-01-01
  • 2011-05-10
  • 2019-10-26
  • 2019-02-27
  • 2017-03-09
相关资源
最近更新 更多