让我这样说:
model.py:
class Task(models.Model):
...
seq_file = models.FileField(upload_to='files/', blank=True, null=True)
...
ajax.py(我正在使用dajaxice,但没关系):
...
def startTask(request, name):
task = Task.objects.get(task_name=name)
data = task.seq_file.open()
filename = os.path.join(settings.MEDIA_ROOT ,task.seq_file.name)
if not os.path.isfile(filename):
raise Exception, "file " + filename + " not found."
sequences = parser.parse(data.read())
...
返回:
File "/home/mnowotka/Dokumenty/MgrFuncAdnot/app/django-gui/src/gui/ajax.py", line 43, in startTask
sequences = parser.parse(data.read())
AttributeError: 'NoneType' object has no attribute 'read'
但:
...
def startTask(request, name):
task = Task.objects.get(task_name=name)
filename = os.path.join(settings.MEDIA_ROOT ,task.seq_file.name)
if not os.path.isfile(filename):
raise Exception, "file " + filename + " not found."
data = open(filename)
sequences = parser.parse(data.read())
...
完美无缺! 为什么呢?
(我正在使用django 1.3)
答案 0 :(得分:29)
因为模型的open方法.FileField不返回任何内容
你可以使用:
task.seq_file.read()
并且您不需要计算文件的路径来检查文件是否存在。你可以使用task.seq_file.path:
if not os.path.isfile(task.seq_file.path):
....
答案 1 :(得分:7)
FileField
将为您提供类似文件的对象,而无需在其上调用open()。在您的示例中,只需致电task.seq_file.file
。
为什么? FileField
有许多存储后端,其中许多不受磁盘中文件的支持(例如,考虑S3存储)。我猜这就是文档说它返回类似文件的对象而不是文件的原因。对于某些类型的存储,“开放”方法毫无意义。
答案 2 :(得分:3)
如有疑问,请检查代码。以下是django.db.models.fields.files
的摘录:
def open(self, mode='rb'):
self._require_file()
self.file.open(mode)
# open() doesn't alter the file's contents, but it does reset the pointer
open.alters_data = True
因此,在FileField
的情况下,open
使用指定的模式重新打开文件。然后,在您拨打open
后,您可以继续使用新应用模式的read
等方法。
答案 3 :(得分:0)
令人惊讶的是,django.db.models.fields.files
没有使用file.storage.exists()
方法,所以我必须实现自己的小函数,以便对实际的物理文件存在进行跨存储兼容检查:
# Check whether actual file of FileField exists (is not deleted / moved out).
def file_exists(obj):
return obj.storage.exists(obj.name)