Django - 如何创建一个文件并将其保存到模型的FileField?
问题描述:
这是我的模型。我想要做的就是生成一个新文件,并覆盖现有每当模型实例保存:Django - 如何创建一个文件并将其保存到模型的FileField?
class Kitten(models.Model):
claw_size = ...
license_file = models.FileField(blank=True, upload_to='license')
def save(self, *args, **kwargs):
#Generate a new license file overwriting any previous version
#and update file path
self.license_file = ???
super(Request,self).save(*args, **kwargs)
我看到大量的文件如何上传文件。但是,如何生成一个文件,将其分配给模型字段并让Django将它存储在正确的位置?
答
您想查看Django文档中的FileField and FieldFile,尤其是FieldFile.save()。
基本上,一个字段声明为FileField
,访问时,给你FieldFile
类的实例,它为您提供了几种方法来与底层文件进行交互。所以,你需要做的是:
self.license_file.save(new_name, new_contents)
其中new_name
是你希望分配的文件名和new_contents
是该文件的内容。请注意0必须是django.core.files.File
或django.core.files.base.ContentFile
的实例(有关详细信息,请参阅指定手册的链接)。有两种选择,可以归结为:
# Using File
f = open('/path/to/file')
self.license_file.save(new_name, File(f))
# Using ContentFile
self.license_file.save(new_name, ContentFile('A string with the file content'))
答
接受的答案无疑是一个很好的解决方案,但这里是我去有关生成CSV并从视图服务的方式。
#Model
class MonthEnd(models.Model):
report = models.FileField(db_index=True, upload_to='not_used')
import csv
from os.path import join
#build and store the file
def write_csv():
path = join(settings.MEDIA_ROOT, 'files', 'month_end', 'report.csv')
f = open(path, "w+b")
#wipe the existing content
f.truncate()
csv_writer = csv.writer(f)
csv_writer.writerow(('col1'))
for num in range(3):
csv_writer.writerow((num,))
month_end_file = MonthEnd()
month_end_file.report.name = path
month_end_file.save()
from my_app.models import MonthEnd
#serve it up as a download
def get_report(request):
month_end = MonthEnd.objects.get(file_criteria=criteria)
response = HttpResponse(month_end.report, content_type='text/plain')
response['Content-Disposition'] = 'attachment; filename=report.csv'
return response
思想,而把这个这里我花了摆弄得到所有期望的行为(覆盖现有文件,保存到正确的位置,而不是创建重复文件等)的一点点很值得。
的Django 1.4.1
的Python 2.7.3
答
感谢@tawmas。除此之外,
如果我在打开文件时未指定文件模式,则出现错误。所以,
f = open('/path/to/file', 'r')
对于ZIP文件的类型,
f = open('/path/to/file.zip', 'rb')
好吧,我认为这会工作,但我进入某种递归循环的调用,在保存方法。它只是不断创建文件。 – Greg
对于递归问题,我必须使用arg save = False调用self.license_file.save。 – Greg
@Greg谢谢你,递归问题真的很烦人。 – laike9m