Django FileField.save() 生成重复文件
我有一些用户提交的内容,想把它写入一个文件,然后保存到一个叫做 FileField
的地方。
我有一个 模型,它看起来是这样的:
class Revision(models.Model):
def custom_revision_file_path(instance, filename):
return '/'.join(['content/revisions', filename])
path = models.FileField(upload_to=custom_revision_file_path)
document = models.ForeignKey(Document)
...
而创建这个实例的 视图 是这样的:
def handle_revisions(request):
document = Document.objects.get(id=request.GET['docid'])
basename = os.path.basename(str(document.path))
revision = Revision.objects.create(
document = document,
)
revision.path.save(basename, ContentFile(request.GET['revision']))
整体上这些都能正常工作,但有两个问题:
1) ContentFile 在我的字符串每个字母之间加了一个空格,所以 'test'
变成了 't e s t'
;
2) 不知道为什么,每次运行这个视图时,都会保存两个 Revision
实例,它们的路径差不多。比如,一个路径是 'content/revisions/test.txt'
,另一个是 'content/revisions/test_1.txt'
,而第二个本来就不应该存在。
这是怎么回事呢?
1 个回答
3
首先,你绝对不应该用那种方式来创建路径:
'/'.join(['content/revisions', filename])
而是应该这样:
os.path.join("my_dir", "my_subdir", ..., "filename.txt")
你不需要知道你的应用是运行在类Unix系统还是Windows上(没错,有些人用Windows作为网页服务器)。
另外,你不应该把你的FileField
属性叫做path
,这样会让人困惑,因为它和FilePathField
的名字很像。
这个字段是NOT NULL
吗?因为在你的create()
语句里你没有提供一个值。这应该会引发一个错误。
我不太明白这个:
revision.path.save(basename, ContentFile(request.GET['revision']))
你想要实现什么?你确定要把一个GET参数存储在文件里吗?
为了回答你的问题,默认情况下,Django不会自动覆盖你文件系统中已经存在的文件,这就是为什么它会自动用一个唯一的路径来存储文件,并添加一个后缀。
如果这种行为不符合你的需求,可以考虑写一个自定义文件存储。