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