模型字段 :
# models.pyfrom django.db import modelsclass UploadModel(models.Model):name = models.CharField(verbose_name="用户", max_length=32)"""先去启用media文件夹, 不启用就自动创建uploads 配合ModelForm使用upload_to="uploads/" 指定文件夹"""file = models.FileField(verbose_name="文件", upload_to="uploads/")def __str__(self):return self.namedef __repr__(self):return self.__str__()class Meta:verbose_name = "文件上传""""# 也可以这样创建, 但是不能指定文件夹, 需要自动保存文件# file2 = models.CharField(verbose_name="文件")"""
1. 手动保存
"""file.name: 上传文件的 名称chunks(): 在 Django 中,chunks() 方法的作用是将大文件分成多个小的块,以便逐块处理,从而减少内存的使用,尤其是在处理上传的文件时。"""with open(f'static/{file.name}', mode='wb') as f:for chunk in file.chunks():f.write(chunk)
1.3 chunks 的源码
1.3.1
1.1 自动保存文件
# views.pyfrom django import forms
from django.shortcuts import render, redirectfrom app01 import modelsdef upload(request):if request.method == "POST":# 获取表单数据username = request.POST.get('username')file = request.FILES.get('file')# 检查用户名和文件是否为空username_error = Nonefile_error = Noneif not username:username_error = "用户名不能为空"if not file:file_error = "文件不能为空"# 如果有错误,返回表单页面并传递错误信息if username_error or file_error:return render(request, 'upload.html', {'username': username,'username_error': username_error,'file_error': file_error})# 如果用户名和文件都存在,保存数据models.UploadModel.objects.create(name=username, file=file)# 上传成功,重定向到后台管理页面return redirect('/admin/app01/uploadmodel/')# 如果是 GET 请求,或者无效的 POST 请求,返回空表单(用于初次加载或错误后回填数据)return render(request, 'upload.html', {'username': request.POST.get('username', '')})
<!-- upload.html --><!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<h1>文件上传</h1><form action="{% url 'upload' %}" method="post" enctype="multipart/form-data" novalidate>{% csrf_token %}<!-- 用户名字段 --><label for="username">用户名:</label><input type="text" id="username" name="username" value="{{ username }}">{% if username_error %}<p style="color: red;">{{ username_error }}</p>{% endif %}<br><!-- 文件上传字段 --><label for="file">上传文件:</label><input type="file" id="file" name="file">{% if file_error %}<p style="color: red;">{{ file_error }}</p>{% endif %}<br><button type="submit">上传</button>
</form></body>
</html>
2. 基于Form
# views.pyfrom django import forms
from django.shortcuts import render, redirectfrom app01 import modelsclass UploadForm(forms.Form):name = forms.CharField(label="用户")file = forms.FileField(label="文件")def upload_form(request):if request.method == "GET":form = UploadForm()return render(request, 'upload_form.html', {'form': form})form = UploadForm(request.POST, request.FILES)if form.is_valid():models.UploadModel.objects.create(name=form.cleaned_data.get('name'), file=form.cleaned_data.get('file'))return redirect('/admin/app01/uploadmodel/')return render(request, 'upload_form.html', {'form': form})
<!-- upload_form.html --><!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<h1>Form上传</h1><form action="{% url 'upload_form' %}" method="post" enctype="multipart/form-data" novalidate>{% csrf_token %}{% for field in form %}<label for="">{{ field.label }}</label>{{ field }}<span style="color: red;">{{ field.errors.0 }}</span><br>{% endfor %}<button type="submit">上传</button>
</form></body>
</html>
3. 基于ModelForm
# views.pyfrom django import forms
from django.shortcuts import render, redirectfrom app01 import modelsclass UploadModelForm(forms.ModelForm):class Meta:model = models.UploadModelfields = "__all__"def upload_model_form(request):if request.method == "GET":form = UploadModelForm()return render(request, 'upload_model_form.html', {'form': form})form = UploadModelForm(request.POST, request.FILES)if form.is_valid():form.save()return redirect('/admin/app01/uploadmodel/')return render(request, 'upload_model_form.html', {'form': form})
<!-- upload_model_form.html --><!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<h1>ModelForm上传</h1><form action="{% url 'upload_model_form' %}" method="post" enctype="multipart/form-data" novalidate>{% csrf_token %}{% for field in form %}<label for="">{{ field.label }}</label>{{ field }}<span style="color: red;">{{ field.errors.0 }}</span><br>{% endfor %}<button type="submit">上传</button>
</form></body>
</html>
4. 暴露文件夹
# 在urls.py中配置from django.urls import re_path
from django.views.static import serveurlpatterns = [re_path(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}, name='media'),
]
# 在settings.py中配置MEDIA_ROOT = os.path.join(BASE_DIR, "media")
MEDIA_URL = "/media/"