Django权限校验场景下,如何自动分配文件Content-Type?
优化Django文件权限验证与Content-Type自动设置方案
一、自动获取Content-Type
不用手动枚举扩展名,直接用Python内置的mimetypes模块就能自动识别文件类型,代码更简洁且覆盖所有常见格式:
先导入模块:
import mimetypes
替换你原来手动判断Content-Type的代码块,改成:
# 自动识别Content-Type content_type, encoding = mimetypes.guess_type(path) # 处理无法识别的情况,默认设为二进制流 content_type = content_type or "application/octet-stream"
二、控制浏览器预览/下载行为
要让浏览器支持的文件在新标签页打开,只需给响应添加Content-Disposition头部设为inline,浏览器会自动判断是否能预览,不能预览的话会自动触发下载:
response['Content-Disposition'] = f'inline; filename="{os.path.basename(path)}"'
三、完整修改后的视图代码
import os import mimetypes from django.contrib.auth.decorators import login_required from django.http import HttpResponse, HttpResponseForbidden from django.conf import settings from .models import Document @login_required def ViewDocument(request, document_id): document = Document.objects.get(id=document_id) path = document.file.name # 验证用户权限(django-guardian) if not request.user.has_perm('home.view_document', document): return HttpResponseForbidden("你没有权限访问该文件。") # 构建文件完整路径 media_path = os.path.join(settings.MEDIA_ROOT, path) # 自动识别Content-Type content_type, encoding = mimetypes.guess_type(path) content_type = content_type or "application/octet-stream" # 读取文件并构建响应 with open(media_path, 'rb') as file: response = HttpResponse(file.read(), content_type=content_type) # 设置浏览器预览/下载行为 response['Content-Disposition'] = f'inline; filename="{os.path.basename(path)}"' return response
额外说明
mimetypes模块会根据系统的mime.types文件识别类型,覆盖绝大多数常见格式(文档、图片、音频、视频等)。- 如果遇到某些特殊格式识别不准确的情况,可以手动补充映射:
mimetypes.add_type("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", ".xlsx") - 若文件名包含中文,为避免乱码,可对文件名进行URL编码:
from urllib.parse import quote response['Content-Disposition'] = f'inline; filename*=UTF-8''{quote(os.path.basename(path))}'
内容的提问来源于stack exchange,提问作者Existn't
相关产品推荐
相关产品推荐

