2012-02-23 6 views
18

は、私はこのようにそれを置くましょう:Django FileField(またはImageField)open()メソッドは、有効なファイルに対してNoneを返しますか?

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()) 
    ... 

は完全に機能します。 なぜですか?

(私はジャンゴ1.3を使用しています)

答えて

25

models.FileFieldのオープン方法は何

を返さないので、あなただけ使用することができます。

task.seq_file.read() 

し、ファイルが存在するかどうかをチェックするために、ファイルのパスを計算する必要はありません。 task.seq_file.pathを使用することができます:

if not os.path.isfile(task.seq_file.path): 
    .... 
+12

FileField open()の目的は何ですか? – mnowotka

+17

残念ながら、Djangoのドキュメントは現在、この点について誤解を招いています: "標準的なPythonのopen()メソッドのように動作します..." - https://docs.djangoproject。 不思議な内部オープン操作を実行した後に「なし」を返すことは、標準的なPythonの動作ではありません。 –

+1

はこれに関する問題を提起するはずです。 – laike9m

7

FileFieldはあなたのファイルのようなオブジェクトを与えるだろうし、その上に)(オープン呼び出す必要はありません。あなたの例では、task.seq_file.fileと呼んでください。

なぜですか? FileFieldには多くのストレージバックエンドがあり、その多くはディスク内のファイルでバックアップされていません(たとえばS3ストレージなど)。ドキュメントでは、ファイルではなくファイルのようなオブジェクトを返すとの理由が考えられます。いくつかの種類のストレージでは、「オープン」方式は意味をなさない。

+1

しかし、ドキュメンテーションFileFieldにはジャンゴによると、ファイルのプロキシです私はそのオブジェクトでopenを呼び出すことができます。私は定義されていないメソッドについてもエラーを起こさなかったので、そこにはありますか?だからバグか、何かを理解していないのですか? – mnowotka

+2

@mnowotka:それはありますが、私はそれを使用したことはありません.FileFieldはファイルのようなオブジェクトを提供しています(すでに "開いています")。 –

+0

FileFieldは必ずしもディスク上のファイル(S3、その他の種類のクラウドストレージ)によってバックアップされているわけではないことに注意してください。 –

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のようなメソッドを引き続き使用できます。驚くべきことに

0

が、file.storage.exists()方法をdjango.db.models.fields.files利用していないので、私は、実際の物理的なファイルの存在のためのクロスストレージ互換性のチェックを持っている私自身の小さな機能を実装する必要がありました:

# Check whether actual file of FileField exists (is not deleted/moved out). 
def file_exists(obj): 
    return obj.storage.exists(obj.name) 
関連する問題