2011-01-29 107 views
2

我上傳文件並將數據存儲在數據庫中。部分元數據是文件名稱本身。然而,在某個地方,文件名似乎沒有得到保存!我只會粘貼我認爲是代碼相關部分的內容,以保持簡短。保存表單後&前Django文件上傳:文件名不粘

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']的值。名稱。無論出於何種原因,它是完整的,但似乎從未將其納入數據庫。

+0

只是一個旁註:一些瀏覽器只發送文件名,其他瀏覽器發送給你整個路徑。 – CodesInChaos 2011-01-29 23:47:27

回答

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等待。我很困惑。你能進一步闡述一下嗎? Noob在這裏。 – Harv 2011-01-30 00:03:44

1

表單字段值不通過表單上的屬性訪問。因此,設置'form.filename'不會將值保存在文件名字段中。相反,請在由form.save()返回的實例上設置值。

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

我只是想補充一點,在未來,您可能會嘗試避免將這種業務邏輯放在模型表單上。雖然WoLpH's的答案是正確的,如何通過ModelForm處理額外的模型實例處理,其依賴於數據在ModelFormModelForm API通過他們的尊敬clean()方法處理,並在幾個被提到的其他領域領域的特定情況下,一個很好的例子放置在官方參考文檔中(這裏是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。這意味着您不必爲通用創建,更新視圖或您的模型的ModelAdmin定義ModelForm,這就是更少的代碼管理!

一般的經驗法則是,您會重新考慮重寫默認行爲是否有理由或獨立,特別是當您在業務邏輯鏈的最遠端工作時,否則您可能會感覺到意外觸發器的憤怒。