3

我想通過我的項目上的窗體上傳一些文件,並將文件保存到磁盤。目前,我能夠將數據插入到數據庫(postgreSQL)中,但數據未寫入磁盤。我已經做了一些環顧四周,並使用modelform,並呼籲save應照顧一切(但顯然我錯過了什麼?)。任何幫助表示讚賞。Django:上傳文件並保存到磁盤

這裏是我的代碼: views.py(上傳相關的作業文件)

# Upload files to a Job (Developer) 
@login_required() 
@user_passes_test(lambda u: u.groups.filter(name='Developer').exists(), login_url='/login/', redirect_field_name='not allowed') 
@require_http_methods(['POST']) 
def job_file_upload(request, jobid): 

    # Get the Job 
    job = Jobs.objects.get(id=jobid) 
    fileform = JobFileSubmitForm(request.POST, request.FILES) 
    if fileform.is_valid(): 
     jfs = fileform.save(commit=False) 
     file = request.FILES['file'] 
     jfs.user_id = request.user.id 
     jfs.job_id = jobid 
     jfs.file = file.name 
     jfs.uploadDate = datetime.now() 
     # Save to DB 
     jfs.save() 

     return redirect('view_job', jobid=jobid, slug=job.slug) 

models.py(DB用於保存文件數據和保持保存到正確路徑)

from django.core.files.storage import FileSystemStorage 

fs = FileSystemStorage(location='/media/') 

... 


def upload_job_file_path(instance, filename): 
    return os.path.join('/uploads/job_meta/files/', instance.id, filename) 


# Submit Files for a Job (Developer Role) 
class JobFileSubmit(models.Model): 
    job = models.ForeignKey(Jobs) 
    user = models.ForeignKey(User) 
    file = models.FileField(storage=fs, upload_to=upload_job_file_path, blank=False, null=False) 
    uploadDate = models.DateTimeField(auto_now=True) 

forms.py

class JobFileSubmitForm(forms.ModelForm): 

    class Meta: 
     model = JobFileSubmit 
     fields = 'file', 

    def save(self, commit=True): 
     jobfilesubmit = super(JobFileSubmitForm, self).save(commit=False) 

     if commit: 
      jobfilesubmit.save() 
     return jobfilesubmit 

view.html

      <form method="post" action="/job/job_file_upload/j{{ job.id }}/" class="form-inline btn-group" enctype="multipart/form-data"> 
           {% csrf_token %} 
           <div class="span6 inline"> 
            <label class="control-label">Attach Files: </label>{{ job_file_submit.file }} 
            <p class="help-block">Attach files that go with this Job.</p> 
           </div> 
           <div class="modal-footer"> 
            <button type="submit" class="btn btn-success btn-med pull-left"><i class="fa fa-check-circle"></i> Attach Files</button> 
            <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> 
           </div> 
          </form> 

TL; DR:目前的形式提交,鑲入DB,但數據不被寫入到磁盤和它應該的動態路徑。例如,數據未被寫入:

/media/uploads/job_meta/files/{{job.id}}/{{file.name}} 

感謝您花時間閱讀本文!任何幫助深表感謝!

+0

看起來像你的upload_job_file_path函數返回一個絕對的文件路徑。 – kanu

+0

啊。它需要是相對的? 如:uploads/job_meta/files /。假設這將MEDIA_ROOT作爲前綴考慮在內? – jaredgilmore

+0

是的。我看到的第二個問題是你的路徑包含job.id,當用新的和未保存的作業調用時,它是None。 – kanu

回答

2

我不知道這是否是最終的答案,但它更容易代碼塊這裏

的upload_job_file_path需要從MEDIA_ROOT返回一個相對路徑寫。 如果我理解正確,那麼id是實例的job_id而不是它的id。 這種方式下面的功能應該工作。 (這可能是FileField或必須在代碼中工作領域下文)

models.py

def upload_job_file_path(instance, filename): 
    return 'uploads/job_meta/files/%s/%s' % (instance.job_id, filename) 


class JobFileSubmit(models.Model): 
    job = models.ForeignKey(Jobs) 
    user = models.ForeignKey(User) 
    file = models.FileField(upload_to=upload_job_file_path, blank=False, null=False) 
    uploadDate = models.DateTimeField(auto_now=True) 

我不是太熟悉modeforms但我想保存方法應該處理文件上傳過。 所以這可能足以

views.py

if fileform.is_valid(): 
    jfs = fileform.save(commit=True) 
+0

哦,我......就是這樣。卡努,我愛你。你剛剛把我的頭髮撕掉了。 – jaredgilmore