12

我在 django 中打开存储在我的数据库中的文本文件时遇到问题。我想通过我的模型的 FileField 访问它......模型看起来像这样

   class MyModel(models.Model):
      saved_file = FileField()

我通过管理界面上传了一个测试文件,它工作正常。在我看来,我想访问这个文件。如果我用标准 python open() 打开它,它可以正常工作......

 f = open(path, 'r')
 a = f.readlines()
 return render_to_response('base.html', {'content': a}, context_instance=RequestContext(request))

这将显示文件的行 ok...根据https://docs.djangoproject.com/en/dev/ref/models/fields/#filefield,当调用模型中的 FileField 时,一个 FieldFile 代理,所以

 f = MyModel.objects.all().get(id=0).saved_file

应该将 FieldFile 存储在 f 中,此外,文档指出通过在 FieldFile 上投射 .open(mode='rb') 从模型中打开一个文件,所以

file = f.open(mode='rb') 

应该像文档中所述的 python .open() 一样工作。所以为了得到线条我做

file.readlines()

应该返回我的行列表。发生的情况是我收到一条错误消息,指出 .readlines() 属性不存在。我不需要文件来显示它,这只是一种测试打开文件是否有效的方法,但我需要在我的视图中将文件内容放在变量中,以便在我的业务逻辑中进一步使用它。任何人都可以建议一种从 FileField 模型中获取文件内容的方法吗?

4

2 回答 2

8

由于 Django 2.0File.open确实返回了一个文件,因此建议的工作方式与上下文管理器一样:

saved_file = MyModel.objects.all().get(id=0).saved_file
with saved_file.open() as f:
    data = f.readlines()

适用于旧版本的 Django < 2

FieldFile.open打开文件,但不返回任何内容。所以在你的例子file中是None.

您应该在 FieldFile 上调用 readlines。在您的示例中,它将是:

f = MyModel.objects.all().get(id=0).saved_file
try:
    f.open(mode='rb') 
    lines = f.readlines()
finally:
    f.close()

UPD:我添加了try/finally块,因为好的做法是始终保留close资源,即使发生异常也是如此。

于 2012-11-16T09:15:38.293 回答
8

文档指出文件默认以“rb”模式打开,但您可能希望以“r”打开以将文件视为文本文件:

my_object = MyModel.objects.get(pk=1)
try:
    my_object.saved_file.open('r')
    lines = my_object.saved_file.readlines()
finally:
    my_object.saved_file.close()

更好的是,您可以在 Django v2.0+ 中使用上下文管理器

my_object = MyModel.objects.get(pk=1)
with my_object.saved_file.open('r') as f:
    lines = f.readlines()
于 2019-04-18T04:36:48.540 回答