2011-12-27 8 views
2

ファイルに書き込もうとしているコンテンツをユーザーが投稿してからFileFieldに保存しました。Django FileField.save()は重複ファイルを作成します

ので、私はこのようになりますモデルあります

class Revision(models.Model): 
    def custom_revision_file_path(instance, filename): 
     return '/'.join(['content/revisions', filename]) 
    path = models.FileField(upload_to=custom_revision_file_path) 
    document = models.ForeignKey(Document) 
    ... 

をしてインスタンスを作成しますビューは次のようになります。

def handle_revisions(request): 
    document = Document.objects.get(id=request.GET['docid']) 
    basename = os.path.basename(str(document.path)) 

    revision = Revision.objects.create(
     document = document, 
    ) 
    revision.path.save(basename, ContentFile(request.GET['revision'])) 

このすべては、比較的細かい動作しますが、用2つの問題:

1)ContentFileは、文字列内の各文字の間にスペースを入れます。'test''t e s t'に変わります。

2)何らかの理由で私がビューを実行するたびに、2つのRevisionインスタンスがほぼ同じパスで保存されます。すなわち、 2つ目のパスが全く存在してはならない場合、一方のパスは'content/revisions/test.txt'になり、もう一方のパスは'content/revisions/test_1.txt'になります。

何がありますか?

+0

この質問には誰でも来てください。私は主により洗練されたソリューションに移行しましたが、http://chronosbox.org/blog/jsonresponse-in-django?lang=enを使用すると、オブジェクトインスタンスを複製するソースが見つかりました。以前はこのモジュールを使っていたので奇妙ですが、ここでうまく動作していないようです。 –

答えて

2

まず第一に、あなたはパスを作成するためにそのようなものを使用しないでください:

'/'.join(['content/revisions', filename]) 

しかし:

os.path.join("my_dir", "my_subdir", ..., "filename.txt") 

あなたは、あなたのアプリケーションが、UNIX上で動作するかどうかを知ることになっていませんまたはWindows(はい、ウェブサーバーとしてWindowsを使用する人もいます)のようになります。

また、FileField属性pathと呼ぶべきではありません。FilePathFieldであいまいです。

このフィールドはNOT NULLですか?あなたのcreate()ステートメントでは、あなたはそれを提供していないからです。これによりエラーが発生するはずです。

私はこれを得ることはありません:

revision.path.save(basename, ContentFile(request.GET['revision'])) 

あなたが達成しようとしていますか?あなたはGETパラメータをファイルに保存してもよろしいですか?

あなたの質問に答えるために、Djangoはファイルシステム上に存在するファイルを上書きする責任を負いません。そのため、接尾辞を追加することで自動的にunique pathで保存します。

この動作が適合しない場合は、custom file storageを作成することを検討してください。

+0

明らかにするには、自分のファイルでRevisionクラスの2つのインスタンスを作成しています。 ContentFile()がファイルを作成し、次に 'revision.path 'を作成する理由を理解していると思います。save() 'はファイルを作成しますが、2番目のリビジョンオブジェクトを作成している場所は表示されません。 –

+0

'MyModel.objects.create()'を2回呼び出すと、データベースに2つのエントリが作成されるためです!レコードを取得または作成するには、 'get_or_create()'を使う必要があります。 'ContentFile'は(ファイルシステム上の)ファイルを作成しません。これはメモリ内の' StringIO'によく似ています。 – Stan

+0

申し訳ありませんが、私は密集しているが、私はまだそれを見ません。私は 'Revision.objects.create()'を一度呼び、 'instance.file_field.save()'を一度呼び出します。あなたが私に実用的な例やいくつかのsudoコードを見せてもらえますか?どこで、なぜ私が 'get_or_create'を使うのかわかりません。私が作業している基本的なリファレンスについては、http://groups.google.com/group/django-users/browse_frm/thread/184e5e09db1efce4/7816cbc650d8dc77をご覧ください。 –

関連する問題