2012-04-10 8 views
4

ファイルがDjango FileFieldとして保存されているハードリンクを使用してファイルをコピーしようとしています。私はスペースとコピー時間を節約するためにハードリンクを使用したいと思います(元のファイルまたはコピーに変更は行われません)。しかし、私は以下のスニペットからnew_file.save()を呼び出そうとすると、幾分奇妙なエラーが出ます。Django:Copy FileFields

AttributeError: 'file' object has no attribute '_committed' 

私の思考は、ハードリンクを作成した後、私はリンクされたファイルを開くことができますし、Djangoの新しいFileのインスタンスのFileFileにそれを保存することです。ここに何か一歩も欠けていますか?

models.py

class File(models.Model): 
    stored_file = models.FileField() 

elsewhere.py

import os 

original_file = File.objects.get(id=1) 
original_file_path = original_file.file.path 

new_file = File() 
new_file_path = '/path/to/new/file' 

os.makedirs(os.path.realpath(os.path.dirname(new_file_path))) 
os.link(original_file_path, new_file_path) 
new_file.stored_file = file(new_file_path) 
new_file.save() 

答えて

8

ありハードリンクを作成する必要はなく、単にファイルホルダーを複製:

new_file = File(stored_file=original_file.stored_file) 
new_file.save() 

更新

あなたはFileFieldにまたはのImageFieldにファイルを指定したい場合は、単に

new_file = File(stored_file=new_file_path) 
# or 
new_file = File() 
new_file.stored_file = new_file_path 
# or 
from django.core.files.base import File 
# from django.core.files.images import ImageFile # for ImageField 
new_file.stored_file = File(new_file_path) 

フィールドがbasestringまたはファイル()インスタンスのパスを受け入れるには、あなたの質問のコードは、ファイルを使用することができ()としたがって受け入れられません。

+0

ご回答ありがとうございます。私がハードリンクを選んだ理由は、新しいFile()インスタンスと別のファイルパスを保存したいからです。私は上記のスニペットで要件が明らかではないと思う - 私はできるだけ簡素化しようとした - しかし、File()モデルのインスタンスに関連付けられているuuidに基づいてファイル名を作成しています。 File()モデルのインスタンスをコピーすると、新しいFile()インスタンスのuuidと一致するように、下敷きのstored_fileパスが必要になります。だからこそ、私はハードリンクに向かって重いものでした。 –

+0

@JoeJ私は、あなたの答えが正しいことを確認します。私の答えも更新しました – okm

2

私はこの問題を解決したと思っていますが、それがなぜ機能するのかはわかりません。私はファイルオブジェクトを "DjangoFile"クラスにラップしました(以前定義したFileモデルとの衝突を避けるためにDjangoFileとしてインポートしました)。

from django.core.files.base import File as DjangoFile 

... 
new_file.stored_file = DjangoFile(file(new_file_path)) 
new_file.save() 

これはファイルOKを保存したようです。