首页 > 解决方案 > 如何使用 django 2.x(或 3)启用批量上传?

问题描述

我有这个接受文件的模型,计算 md5 总和,如果该值尚未在数据库中,则存储文件。它一次只适用于一个文件。

# models.py
class RawFile(models.Model):
    # use the custom storage class fo the FileField
    orig_file = models.FileField(
        upload_to=media_file_name, storage=file_system_storage)
    md5sum = models.CharField(max_length=36, default=timezone.now, unique=True)
    created = models.DateField(default=timezone.now)

    def save(self, *args, **kwargs):
        print('Saving new raw file.', self.md5sum)
        if not self.pk:  # file is new
            md5 = hashlib.md5()
            for chunk in self.orig_file.chunks():
                md5.update(chunk)
            self.md5sum = md5.hexdigest()
        if not self.id:
            self.created = timezone.now()
        print('Saving new raw file.', self.md5sum)
        super(RawFile, self).save(*args, **kwargs) 

    def __str__(self):
        return basename(self.orig_file.name)

    @property
    def abs_path(self): 
        return f'{MEDIA_ROOT}/{self.orig_file}'

    @property
    def filename(self):
        return basename(self.abs_path)

    @property
    def rawtools_status(self):
        path = dirname(self.abs_path)
        if isfile('QcDataTable.csv'):
            return 'Done'
        elif isfile(join(path, 'rawtools.txt')):
            return 'Running'
        return 'New file'

    @property    
    def href(self):
        return os.path.dirname('/'+self.orig_file.name)

    def link(self):
        print(self.href)
        return mark_safe(r'<a href="{}">Output</a>'.format(self.href))

    link.short_description = 'Browse'


# pipelines/forms.py

from django import forms
from .models import RawFile

我更改了上传表单,以便可以同时上传多个文件,尽管这里只存储了批处理中的最后一个文件。

# forms.py
class UploadRawForm(forms.ModelForm):
    orig_file = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))
    class Meta:
        model = RawFile
        fields = ['orig_file']

    error_css_class = 'error'
    required_css_class = 'required'

如何归档多文件上传,以便在后端单独处理每个文件?

更新:使用此代码,多个文件上传似乎可以工作。

# views.py
from django.shortcuts import render, redirect
from django.views import generic
from .forms import UploadRawForm
from .models import RawFile

def upload_raw_view(request):
    '''Upload RAW files. Working for single file uploads'''
    form = UploadRawForm()
    if request.method == 'POST':
        form = UploadRawForm(request.POST, request.FILES)
        if not form.is_valid():
            return render(request, 'pipelines/upload.html', context={'form': form})
        if form.is_valid():
            files = request.FILES.getlist('orig_file')
            for f in files:
                rawfile = RawFile(orig_file = f)
                rawfile.save()
            return render(request, 'pipelines/upload.html', {'form': form})
    return render(request, 'pipelines/upload.html', {'form': form})

标签: django

解决方案


您尚未发布如何在视图中处理表单,但我认为您需要对包含多个值的字段使用“getlist”,如下所示

files = request.FILES.getlist('orig_file')
if form.is_valid():
   for f in files:
       rawfile = RawFile(orig_file = f)
       rawfile.save()

有关详细信息,请参阅文档


推荐阅读