777ca50328
update. 调整融合主菜单与板块 update. 分离新闻模块
96 lines
2.9 KiB
Python
96 lines
2.9 KiB
Python
import os
|
|
import hashlib
|
|
from datetime import datetime
|
|
|
|
|
|
def _get_file_md5(file_obj):
|
|
"""
|
|
通用辅助函数:计算任意文件对象的 MD5
|
|
"""
|
|
md5 = hashlib.md5()
|
|
|
|
# 关键步骤:重置文件指针到开头
|
|
# 因为 Django 在处理上传时可能已经读取了一部分文件头
|
|
try:
|
|
file_obj.seek(0)
|
|
except Exception:
|
|
pass
|
|
|
|
# 分块读取计算,防止大文件撑爆内存
|
|
for chunk in file_obj.chunks():
|
|
md5.update(chunk)
|
|
|
|
# 计算完后再次重置指针,确保不影响 Django 后续的保存操作
|
|
try:
|
|
file_obj.seek(0)
|
|
except Exception:
|
|
pass
|
|
|
|
return md5.hexdigest()
|
|
|
|
|
|
def upload_image_and_rename(instance, filename):
|
|
"""
|
|
通用图片上传处理函数
|
|
逻辑:存入 images/年/月/日/md5.ext
|
|
"""
|
|
# 1. 获取后缀
|
|
ext = os.path.splitext(filename)[1].lower()
|
|
|
|
# 2. 生成日期路径
|
|
date_str = datetime.now().strftime('%Y/%m/%d')
|
|
|
|
# 3. 计算 MD5
|
|
# 这里直接利用传入的 filename 对应的文件对象(在内存或临时文件中)
|
|
# 注意:这里假设 filename 是有效的 UploadedFile 对象名称,
|
|
# 但最稳妥的方式其实是直接操作 file_obj。
|
|
# 由于 upload_to 签名限制,我们通常通过 instance 获取字段值,
|
|
# 但为了通用性,我们尝试从 instance 的 __dict__ 中寻找 FileField 对象。
|
|
|
|
file_obj = None
|
|
# 遍历 instance 的所有属性,找到第一个 FileField 类型的值
|
|
for field in instance._meta.get_fields():
|
|
if hasattr(field, 'upload_to') and hasattr(instance, field.name):
|
|
val = getattr(instance, field.name)
|
|
if val and hasattr(val, 'chunks'): # 确认是文件对象
|
|
file_obj = val
|
|
break
|
|
|
|
# 如果找不到文件对象(极少见情况),使用随机字符串防止报错
|
|
if not file_obj:
|
|
import uuid
|
|
new_filename = f"{uuid.uuid4().hex}{ext}"
|
|
else:
|
|
md5_hash = _get_file_md5(file_obj)
|
|
new_filename = f"{md5_hash}{ext}"
|
|
|
|
# 4. 返回路径
|
|
return os.path.join('images', date_str, new_filename)
|
|
|
|
|
|
def upload_file_and_rename(instance, filename):
|
|
"""
|
|
通用文件上传处理函数
|
|
逻辑:存入 uploads/年/月/日/md5.ext
|
|
"""
|
|
ext = os.path.splitext(filename)[1].lower()
|
|
date_str = datetime.now().strftime('%Y/%m/%d')
|
|
|
|
file_obj = None
|
|
# 同样的通用查找逻辑
|
|
for field in instance._meta.get_fields():
|
|
if hasattr(field, 'upload_to') and hasattr(instance, field.name):
|
|
val = getattr(instance, field.name)
|
|
if val and hasattr(val, 'chunks'):
|
|
file_obj = val
|
|
break
|
|
|
|
if not file_obj:
|
|
import uuid
|
|
new_filename = f"{uuid.uuid4().hex}{ext}"
|
|
else:
|
|
md5_hash = _get_file_md5(file_obj)
|
|
new_filename = f"{md5_hash}{ext}"
|
|
|
|
return os.path.join('uploads', date_str, new_filename)
|