24.Django上传文件

简单上传

forms.py

from django import forms

class FileForm(forms.Form):
    name = forms.CharField(max_length=20)

    file = forms.FileField()

views.py

from django.shortcuts import render,redirect
import os

from .forms import FileForm

# 处理上传的文件 可以写在任何位置
def handle_uploaded_file(f):
    with open('/Desktop/1.txt', 'wb+') as destination:
        for chunk in f.chunks():
            destination.write(chunk)

def file_upload(request):
    if request.method == 'POST':
        # 文件上传的表单
        form = FileForm(request.POST, request.FILES)

        if form.is_valid():
            handle_uploaded_file(request.FILES['file'])
            return redirect('/')
    else:
        form = FileForm()
        return render(request, 'upload.html', {'form': form})

上传必须使用post提交,并且

必须包含enctype="multipart/form-data"

模版:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/" enctype="multipart/form-data" method="post">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="upload">
</form>

</body>
</html>

urls.py

from upload.views import file_upload

urlpatterns = [
    path('admin/', admin.site.urls),
    path('upload/',file_upload),
    path('',file_upload),

]

使用FileModel上传

models.py

from django.db import models


class FileModel(models.Model):
    file = models.FileField(upload_to= './files')

upload_to:必须是相对路径
forms.py

from django import forms

from .models import FileModel

class ModelFormWithFileField(forms.ModelForm):
    class Meta:
        model = FileModel
        fields = ['file']

views.py

from .forms import ModelFormWithFileField

def file_upload(request):
    if request.method == 'POST':
        form = ModelFormWithFileField(request.POST, request.FILES)

        if form.is_valid():
            form.save()
            return redirect('/')
    else:
        form = ModelFormWithFileField()
        return render(request, 'upload.html', {'form': form})

模版无需修改,即可大道同样的上传效果。

多文件上传

forms.py
如果要使用一个表单字段同时上传多个文件,需要设置字段HTML标签的multiple属性为True

from django import forms

class FileFieldForm(forms.Form):
    name = forms.CharField(max_length=20)

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

views.py
编写一个FormView的子类,并覆盖它的post方法,来处理多个文件上传

from django.views.generic import FormView

from .forms import FileFieldForm

class FileFieldView(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:
                # 处理文件
            return self.form_valid(form)
        else:
            return self.form_invalid(form)

文件处理器

上传文件的时候Django使用文件处理器来处理文件。
默认配置:

FILE_UPLOAD_HANDLERS = ["django.core.files.uploadhandler.MemoryFileUploadHandler",
 "django.core.files.uploadhandler.TemporaryFileUploadHandler"]

Django的默认文件上传行为:将小文件(<2.5M)读取到内存中,大文件放置在磁盘中

声明:原创文章,版权所有,转载请注明出处,https://litets.com。