Django4.0 文件上傳-簡單文件上傳

2022-03-16 17:43 更新

考慮一個(gè)包含 ?FileField ?的表單:

from django import forms

class UploadFileForm(forms.Form):
    title = forms.CharField(max_length=50)
    file = forms.FileField()

處理這個(gè)表單的視圖將在 ?request.FILES? 中接收文件數(shù)據(jù),它是一個(gè)字典,包含表單中每個(gè) ?FileField ?(或 ?ImageField?,或其他 ?FileField ?子類)的鍵。所以上述表單中的數(shù)據(jù)將以 ?request.FILES['file']? 的形式被訪問。
注意 ?request.FILES? 只有當(dāng)請求方法是 ?POST?,至少有一個(gè)文件字段被實(shí)際發(fā)布,并且發(fā)布請求的 ?<form>? 有 ?enctype="multipart/form-data"? 屬性時(shí),才會包含數(shù)據(jù)。否則 ?request.FILES? 將為空。
大多數(shù)情況下,你需要像將上傳的文件綁定到表單中 里描述的那樣將文件數(shù)據(jù)從 ?request ?傳遞給表單。示例如下:

from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import UploadFileForm

# Imaginary function to handle an uploaded file.
from somewhere import handle_uploaded_file

def upload_file(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            handle_uploaded_file(request.FILES['file'])
            return HttpResponseRedirect('/success/url/')
    else:
        form = UploadFileForm()
    return render(request, 'upload.html', {'form': form})

注意我們必須將 ?request.FILES? 傳入到表單的 構(gòu)造方法中,只有這樣文件數(shù)據(jù)才能綁定到表單中。
我們通??赡芟襁@樣處理上傳文件:

def handle_uploaded_file(f):
    with open('some/file/name.txt', 'wb+') as destination:
        for chunk in f.chunks():
            destination.write(chunk)

使用 ?UploadedFile.chunks()? 而不是 ?read()? 是為了確保即使是大文件也不會將我們系統(tǒng)的內(nèi)存占滿。

通過模板來處理上傳的文件

如果想要在 ?FileField ?上的 ?Model ?保存文件,使用 ?ModelForm ?會讓這一過程變得簡單。當(dāng)調(diào)用 ?form.save()? 時(shí),文件對象將會被保存在對相應(yīng) ?FileField ?的 ?upload_to ?參數(shù)所指定的地方:

from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import ModelFormWithFileField

def upload_file(request):
    if request.method == 'POST':
        form = ModelFormWithFileField(request.POST, request.FILES)
        if form.is_valid():
            # file is saved
            form.save()
            return HttpResponseRedirect('/success/url/')
    else:
        form = ModelFormWithFileField()
    return render(request, 'upload.html', {'form': form})

如果你準(zhǔn)備手工構(gòu)建對象,你可以指定來自 ?request.FILES? 的文件對象到模型里的文件對象:

from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import UploadFileForm
from .models import ModelWithFileField

def upload_file(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            instance = ModelWithFileField(file_field=request.FILES['file'])
            instance.save()
            return HttpResponseRedirect('/success/url/')
    else:
        form = UploadFileForm()
    return render(request, 'upload.html', {'form': form})

如果您在請求之外手動(dòng)構(gòu)建對象,則可以將類似文件的對象分配給 ?FileField?:

from django.core.management.base import BaseCommand
from django.core.files.base import ContentFile

class MyCommand(BaseCommand):
    def handle(self, *args, **options):
        content_file = ContentFile(b'Hello world!', name='hello-world.txt')
        instance = ModelWithFileField(file_field=content_file)
        instance.save()

上傳多個(gè)文件

如果你想使用一個(gè)表單字段上傳多個(gè)文件,則需要設(shè)置字段的 ?widget的 ?multiple HTML? 屬性。

from django import forms

class FileFieldForm(forms.Form):
    file_field = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))

然后覆蓋 ?FormView ?子類的 ?post ?方法來控制多個(gè)文件上傳:

from django.views.generic.edit import FormView
from .forms import FileFieldForm

class FileFieldFormView(FormView):
    form_class = FileFieldForm
    template_name = 'upload.html'  # Replace with your template.
    success_url = '...'  # Replace with your URL or reverse().

    def post(self, request, *args, **kwargs):
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        files = request.FILES.getlist('file_field')
        if form.is_valid():
            for f in files:
                ...  # Do something with each file.
            return self.form_valid(form)
        else:
            return self.form_invalid(form)


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號