Django的最佳实践文件上传
问题描述:
综上所述,我想在这里完成替换旧文件是:Django的最佳实践文件上传
- 要为组织和安全起见进行了上传文件的名称转变
- 不再保留旧的文件永远在存储
假设你有一个Company
模型有一个标志。像
class Company(models.Model):
name = ...
logo = models.FileField(blank=True, null=True)
现在的东西,因为我是一个有点偏执,我真的不喜欢那个上传的文件获得通过(潜在的邪恶)用户的名称是事实,我添加了一个upload_to
参数指向一个功能就像
def logo_getfilename(instance, filename):
extension = ... # get just the original extension from the file
return 'logos/' + str(uuid.uuid4()) + extension
好的,所以现在只有视图丢失了!
def company_edit(request, ...):
company = ... # get the company and stuff
if request.method == 'POST':
form = CompanyAdminForm(request.POST, request.FILES, instance=company)
last_file_path = None
if not company.logo is None:
last_file_path = company.logo.path
# ^^ after calling is_valid(), file_path gets changed to
# the would-be-default-behavior
if form.is_valid():
# first we write the new file
form.save()
# now we remove the old one
os.unlink(last_file_path)
虽然这是目前工作的,我不是因为
- 我使用
os.unlink()
代替FieldFile.delete()
这似乎是错的很舒服 - 我假设一个本地文件系统存储
- 我仍然没有做任何反对命名冲突的事情(他们可能仍然会发生)
- 我忽略了多个块,并假设
form.save()
负责一切 - 我不考虑交易行为(以前的文件应只有在
.save()
模式变化将提交给数据库中删除 - 我感觉有一些问题,有我甚至不知道
因此,为了实现这些简单(并且不那么罕见)的目标,您的建议是什么?
答
为什么不使用公司的主键而不是随机输入用户名?当他们上传一个新文件时,只需要覆盖现有的文件(我认为只要在保存之前更改文件名,它就会自动执行)。这应该删除您需要做os.unlink
和(也许)停止您的交易担心。