2011-01-29 3 views
2

私はファイルをアップロードし、メタデータをdbに保存しています。メタデータの一部はファイル名そのものです。しかし、どこかの行の下にファイル名が保存されていないようです!私はこれを短く保つためにコードの関連部分であると思うものだけを貼り付けます。Django file upload:ファイル名が固まらない

class UploadFile(models.Model): 
    ... 
    theFile = models.FileField(upload_to = "Genius/Uploads/", null = True) 
    filename = models.CharField(max_length = 50, blank = True, null = False) 

class UploadFileForm(ModelForm): 
    class Meta: 
     model = UploadFile 
     fields = ('title', 'theFile', 'date_uploaded',) # Don't prompt for filename 


def files_upload(request): 
    if request.method == 'POST': 
     form = UploadFileForm(request.POST, request.FILES) 
     if form.is_valid(): 
      form.filename = request.FILES['theFile'].name # TODO: sanitize! 
      # form.filename = 'foo' 
      form.save() 
      return HttpResponseRedirect('/files/upload/successful/') 
     else: 
      form = UploadFileForm() 
     return render_to_response('files/upload_file.html', { 'form': form }) 

私はrequest.FILES [ 'theFile']の値をチェックしてきた。名前を&前に、フォームを保存した後。どんな理由であれ、それは損なわれませんが、決してそれをDBにするようなことはありません。

+0

ちょうど傍注:一部のブラウザはあなたにファイル名を送信し、他のブラウザはあなたに全体のパスを送信します。 – CodesInChaos

答えて

2

form.filenameはフォームフィールドであり、保存する値ではないからです。あなたはこのような何かを探している

class UploadFileForm(ModelForm): 
    def save(self, commit=True): 
     instance = ModelForm.save(self, commit=False) 
     instance.filename = self.files['theFile'].name 

     if commit: 
      instance.save() 

     return instance 

    class Meta: 
     model = UploadFile 
     fields = ('title', 'theFile', 'date_uploaded',) # Don't prompt for filename 

代替ソリューションは:

upload_file = form.save(commit=False) 
upload_file.filename = request.FILES['theFile'].name 
upload_file.save() 
+0

ああしたがって、upload_fileはインスタンスになります。err wait。よくわかりません。あなたはさらに精緻化できますか?ここのNoob。 – Harv

+0

@ハルヴ:あなたは正しい。 'form.save()'メソッドはインスタンスを返します(そして 'commit = True'で、最初に保存します)。他にもいくつかのオプションがありますが、 'filename'フィールドをフォームに追加して、' data'引数をフォームに変更することができます。フォームの 'save()'メソッドを変更すると、自動的にフォームの中でこれを行います( 'self.files'をフォーム内で利用可能にする必要があります)。 – Wolph

+0

よかった、素晴らしい。私のためにそれをクリアしてくれてありがとう。そしてすぐに答えるために! – Harv

1

フォームフィールドの値は、フォーム上の属性を介してアクセスされていません。したがって、 'form.filename'を設定しても、filenameフィールドに保存される値は設定されません。代わりに、form.save()によって返されたインスタンスの値を設定します。

upload_file = form.save(commit=False) 
upload_file.filename = filename 
upload_file.save() 
0

私は将来、モデル・フォームにそのようなビジネス・ロジックを置かないようにしようと考えています。 WoLpH'sの回答は正解であり、ModelFormを通して追加モデルインスタンス処理を処理する方法の大きな例であるが、他のフィールドデータに依存するフィールドを有する特定のケースは、それらの尊重されたclean()メソッドを介してModel,FormおよびModelForm APIで処理され、公式のリファレンスドキュメント(ここではformsにありますが、ModelModelForm APIについても同様です)。

import os 

class UploadFile(models.Model): 

    # ... 

    def clean(self): 
      # Field data has already been populated by this point. 
      # Note that `FieldFile` inherits from `File` and that 
      # `File.name` is actually the full path to the file 
      # so we need to get the base path component sans the extension 

      path, extension = os.path.splitext(self.thefile.file.name) 
      self.filename = os.path.basename(path) 

をそして、それはそれについてです:あなたのケースでは

は、これは意味します!モデルフィールドにeditable属性を正しく設定すると、Djangoを使用してUploadFileモデルのModelFormを自動的に生成することができます。つまり、一般的な作成、更新ビュー、またはモデルのModelAdminModelFormを定義する必要はなく、管理するコード行が少なくて済みます。

大まかに言えば、特にビジネスロジックチェーンの遠端で作業しているときに、デフォルトの動作のオーバーライドが正当であるか自己完結的であるかについて2回考えていることです。そうでなければ、予期しないフロップの怒りを感じるかもしれません。

関連する問題