2009-07-27 12 views
121

ユーザーのjoeがファイルをアップロードすると、すべてのファイルをMEDIA_ROOTに移動するのではなく、MEDIA_ROOT/joeに移動するようにアップロードを設定しようとしています。問題は、モデルでこれを定義する方法がわからないことです。現在の外観は次のとおりです。Django FileFieldでupload_toが実行時に決定される

class Content(models.Model): 
    name = models.CharField(max_length=200) 
    user = models.ForeignKey(User) 
    file = models.FileField(upload_to='.') 

だから、私が望むものは '。 upload_toとして、それがユーザーの名前になるようにします。

Django 1.0では、upload_toを処理する独自の関数を定義することができますが、その関数はどちらがユーザーになるかわからないことを理解しています。

ありがとうございました!おそらくので、ここで、the documentationを読んだ

答えて

242

は、それが意味をなすようにする簡単な例です:

def content_file_name(instance, filename): 
    return '/'.join(['content', instance.user.username, filename]) 

class Content(models.Model): 
    name = models.CharField(max_length=200) 
    user = models.ForeignKey(User) 
    file = models.FileField(upload_to=content_file_name) 

あなたが見ることができるように、あなたも、与えられたファイル名を使用する必要はありません - あなたはそれをオーバーライドすることができますもしあなたが好きなら、あなたのupload_toも呼び出し可能です。

+0

ええ、それはおそらくドキュメントに属しています - それはIRCの合理的なFAQです – SmileyChris

+2

これはModelFormで動作しますか?私はインスタンスがクラスモデルのすべての属性を持っていることがわかりますが、値はありません(フィールド名のstrだけです)。テンプレートでは、ユーザーは非表示になっています。私は質問を提出しなければならないかもしれませんが、私はこれを何時間もグーグルで探しています。 – mgag

+0

はい、動作します。はい、新しい質問をする必要があります(または#django ircのヘルプを依頼する必要があります) – SmileyChris

11

これは本当に助けになりました。もう少し簡潔のために、私の場合には、ラムダを使用することにしました:

file = models.FileField(
    upload_to=lambda instance, filename: '/'.join(['mymodel', str(instance.pk), filename]), 
) 
+2

これはDjango 1.7でマイグレーションを使って私にとってはうまくいきませんでした。代わりに関数を作成し、移行が完了しました。 – aboutaaron

+0

str(instance.pk)を使用してlambdaを動作させることができない場合でも、ファイルを上書きしたくない場合に問題がある場合は、それをお勧めします。 –

+0

インスタンスに保存する前に 'pk'がありません。これは、作成ではなく更新(挿入)の場合にのみ機能します。 –

3

ノートを「インスタンスのオブジェクトのPK値を使用して。

ほとんどの場合、このオブジェクトはデータベースにまだ保存されていないため、デフォルトの自動フィールドを使用している場合、主キーフィールドの値はまだない可能性があります。

したがって、pkを使用する妥当性は、特定のモデルの定義方法によって異なります。

+0

私は値としてNoneを取得しています。私はそれを修正する方法を把握することはできません。あなたは少し詳しく説明できますか? –

関連する問題