首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Django -如何创建文件并保存到模型的FileField?

Django -如何创建文件并保存到模型的FileField?
EN

Stack Overflow用户
提问于 2011-09-22 20:49:25
回答 3查看 117.9K关注 0票数 139

这是我的模型。我想要做的是生成一个新文件,并在保存模型实例时覆盖现有文件:

代码语言:javascript
复制
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将其存储在正确的位置?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-09-22 21:07:41

您需要在Django文档中查看FileField and FieldFile,尤其是FieldFile.save()

基本上,声明为FileField的字段在被访问时会提供一个FieldFile类的实例,该实例提供了几种与底层文件交互的方法。所以,你需要做的是:

代码语言:javascript
复制
self.license_file.save(new_name, new_contents)

其中,new_name是您希望分配的文件名,new_contents是文件的内容。请注意,new_contents必须是django.core.files.Filedjango.core.files.base.ContentFile的实例(有关详细信息,请参阅手册的给定链接)。

这两个选择可以归结为:

代码语言:javascript
复制
from django.core.files.base import ContentFile, File

# Using File
with open('/path/to/file') as f:
    self.license_file.save(new_name, File(f))

# Using ContentFile
self.license_file.save(new_name, ContentFile('A string with the file content'))
票数 189
EN

Stack Overflow用户

发布于 2013-02-15 06:18:33

公认的答案当然是一个很好的解决方案,但以下是我从一个角度生成CSV并为其提供服务的方法。

我认为把这个放在这里是值得的,因为我花了一点时间才得到所有想要的行为(覆盖现有文件,存储到正确的位置,不创建重复文件等)。

Django 1.4.1

Python 2.7.3

代码语言:javascript
复制
#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
票数 29
EN

Stack Overflow用户

发布于 2019-09-07 01:14:03

最好使用上下文管理器,或者在文件保存过程中出现异常的情况下调用close()。如果您的存储后端停机,则可能发生这种情况,等等。

任何覆盖行为都应该在您的存储后端进行配置。例如,S3Boto3Storage有一个设置AWS_S3_FILE_OVERWRITE。如果你使用的是FileSystemStorage,你可以写一个custom mixin

如果您希望发生任何自定义的副作用,比如上次更新的时间戳,您可能还希望调用模型的save方法,而不是FileField的save方法。如果是这样的话,您还可以将文件的名称属性设置为文件的名称-这是相对于MEDIA_ROOT的。它缺省为文件的完整路径,如果不设置它,可能会导致问题-请参阅File.__init__()File.name

下面是一个示例,其中self是模型实例,my_file是FileField / ImageFile,在整个模型实例上调用save(),而不仅仅是FileField:

代码语言:javascript
复制
import os
from django.core.files import File

with open(filepath, 'rb') as fi:
    self.my_file = File(fi, name=os.path.basename(fi.name))
    self.save()
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7514964

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档