12 Django上传文件
1 form表单上传文件
enctype="multipart/form-data"在上传文件时,必须写上此参数,可以上传文件也可以上传普通健值如果不填写,则默认是
enctype="application/x-www-form-urlencoded"
<h3>form表单上传文件</h3>
<form action="/upload_file/" method="post" enctype="multipart/form-data">
<p><input type="file" name="stu_jpg"></p>
<input type="submit">
</form>
def index(request):
return render(request,"index.html")
def form_rec(request):
# 1.获取数据
stu_jpg = request.FILES.get('stu_jpg')
print("FILES:", stu_jpg)
# 2.保存文件
import os
path = os.path.join('media', stu_jpg.name)
with open(path, 'wb') as f:
for line in stu_jpg:
f.write(line)
return HttpResponse('上传成功')
2 Ajax(基于FormData)
FormData是什么呢?
XMLHttpRequest Level 2添加了一个新的接口FormData.利用FormData对象,我们可以通过JavaScript用一些键值对来模拟一系列表单控件,我们还可以使用XMLHttpRequest的send()方法来异步的提交这个"表单".比起普通的ajax,使用FormData的最大优点就是我们可以异步上传一个二进制文件.
所有主流浏览器的较新版本都已经支持这个对象了,比如Chrome 7+、Firefox 4+、IE 10+、Opera 12+、Safari 5+。
<h3>Ajax上传文件</h3>
<p><input type="text" name="username" id="username" placeholder="username"></p>
<p><input type="file" name="upload_file_ajax" id="upload_file_ajax">
</p>
<button id="upload_button">提交</button>
<span class="err"></span>
{#注意button标签不要用在form表单中使用#}
<script>
$("#upload_button").click(function(){
var username=$("#username").val();
var upload_file=$("#upload_file_ajax")[0].files[0];
var formData=new FormData();
formData.append("username",username);
formData.append("upload_file_ajax",upload_file);
$.ajax({
url:"/upload_file/",
type:"POST",
data:formData,
contentType:false,
processData:false,
success: function (res) {
console.log(res)
if (res.state){
$('.err').html(res.msg)
}else {
$('.err').html(res.msg)
}
}
});
})
</script>
def index(request):
return render(request,"index.html")
def upload_file(request):
# 1.获取数据
stu_jpg = request.FILES.get('username')
print("FILES:", stu_jpg)
# 2.保存文件
import os
path = os.path.join('media', stu_jpg.name)
with open(path, 'wb') as f:
for line in stu_jpg:
f.write(line)
res = {'state': True, 'msg': "ajax上传成功"}
return JsonResponse(res)
3 ImageField 和 FileField
ImageField 和 FileField 可以分别对图片和文件进行上传到指定的文件夹中。
1.在下面的 models.py 中 :
picture = models.ImageField(upload_to='avatars/', default="avatars/default.png",blank=True, null=True)
# 注:定义 ImageField 字段时必须制定参数 upload_to这个字段要写相对路径,
这个参数会加在 settings.py 中的 MEDIA_ROOT后面, 形成一个路径, 这个路径就是上 传图片的存放位置,默认在Django项目根路径下,也就是MEDIA_ROOT默认是Django根目录
所以要先设置好 mysite/settings.py中的 settings.py 中的 MEDIA_ROOT
class Userinfo(models.Model):
name = models.CharField(max_length=32)
avatar_img = models.FileField(upload_to="avatars/")
# 上传的文件,存放在Django下的 media/avatars 文件夹下
username = request.POST.get("username")
#获取文件对象
file = request.FILES.get("file")
#插入数据,将图片对象直接赋值给字段
user = Userinfo.objects.create(name=username,avatar_img=file)
Django会在项目的根目录创建avatars文件夹,将上传文件下载到该文件夹中,avatar字段保存的是文件的相对路径。
2.在 mysite/settings.py中 :
MEDIA_ROOT = os.path.join(BASE_DIR,"media")
MEDIA_URL='/media/'
MEDIA_ROOT:存放 media 的路径, 这个值加上 upload_to的值就是真实存放上传图片文件位置
MEDIA_URL:给这个属性设值之后,静态文件的链接前面会加上这个值,如果设置这个值,则UserInfo.avatar.url自动替换成:/media/avatars/default.png,可以在模板中直接调用:
。
3.url.py:
from django.views.static import serve
# 添加media 配置
re_path(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
浏览器可以直接访问http://127.0.0.1:8000/media/yuan/avatars/%E7%86%8A%E7%8C%AB.webp,即我们的用户上传文件。
最后再给大家补充一个用户文件夹路径:动态路径字符串
def user_directory_path(instance, filename):
# instance当前的数据,filename 文件夹名称
return os.path.join(instance.name,"avatars", filename)
class Userinfo(models.Model):
name = models.CharField(max_length=32)
avatar_img = models.FileField(upload_to=user_directory_path)
4.FileField 和 ImageFiled 相同。
5.示例:
settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
MEDIA_URL = "/media/"
urls.py
from django.contrib import admin
from django.urls import path, re_path
from app01.views import index, create_user
from django.views.static import serve
from Uploads import settings
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', index),
path('create_user/', create_user),
re_path(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
]
views.py
def index(request):
return render(request, 'index.html')
def create_user(request):
res = {'state': True, 'msg': "ajax上传成功"}
username = request.POST.get("user")
file = request.FILES.get("file")
user = UserInfo.objects.create(name=username, avatar_img=file)
res['username'] = user.name
# user.avatar_img
res['avatar_url'] = user.avatar_img.url
return JsonResponse(res)
models.py
from django.db import models
import os
def user_directory_path(instance, filename):
# instance当前的数据avatar_img,filename 文件夹名称
return os.path.join(instance.name, "avatars", filename)
class UserInfo(models.Model):
name = models.CharField(max_length=32)
avatar_img = models.ImageField(upload_to=user_directory_path)
# upload_to="/uploads/" :相对路径
index.html
<h3>ImageField/FileField上传</h3>
<div>
<input type="text" class="user">
<input type="file" class="stu_avatar">
<button class="ajax_btn2">ajax提交</button>
<span class="err2"></span>
<p>用户名:<span class="user"></span></p>
<p>用户头像路径:<span class="avatar_url"></span></p>
<p class="avatar_img"></p>
</div>
<script>
$(".ajax_btn2").click(function () {
var formData = new FormData();
formData.append("user", $('.user').val());
formData.append("file", $('.stu_avatar')[0].files[0]);
formData.append("csrfmiddlewaretoken", $("[name='csrfmiddlewaretoken']").val());
$.ajax({
url: "/create_user/",
type: "post",
data: formData,
contentType: false,
processData: false,
success: function (res) {
console.log(res)
if (res.state){
$('.err2').html(res.msg)
$('.user').html(res.username)
$('.avatar_url').html(res.avatar_url)
$('.avatar_img').append(`<img src="${res.avatar_url}">`)
}else {
$('.err2').html(res.msg)
}
}
})
})
</script>
4 导入表格批量创建数据
# Create your tests here.
def multi_create(request):
# 将接受到的excel文件转到mysql
# (1)下载文件到服务器
emp_excel = request.FILES.get("emp_excel")
print(emp_excel) # 期末题目(陕西联通).xlsx
print(emp_excel.name) # "期末题目(陕西联通).xlsx"
# 下载文件
with open("files/"+emp_excel.name,"wb") as f:
for line in emp_excel:
f.write(line)
# 读取excel,批量导入到mysql中
import os
from openpyxl import load_workbook
file_path = os.path.join("files",emp_excel.name)
# 加载某一个excel文件
wb = load_workbook(file_path)
# 获取sheet对象
print("wb.sheetnames",wb.sheetnames)# 获取所有工作簿的名字
worksheet = wb.worksheets[0] # 获取execl表中的第一个工作薄对象
stu_list = []
for line in worksheet.iter_rows(min_row=3): # 用一行数据拿一行数据;从第三行拿数据
# print("line", line)
# for cell in line: # 取每一行的单元格
# print(cell.value) # 拿去单元格的值
if line[0].value == None:
break
sd = StudentDetail.objects.create(tel=line[4].value, addr=line[5].value) # 创建学生详情信息
class_id = Clas.objects.get(name=line[-1].value).id # 获取班级id
if line[2].value == "男":
sex = 1
elif line[2].value == "女":
sex = 0
else:
sex = 2
stu = Student(
name=line[0].value,
age=line[1].value,
sex=sex,
birthday=line[3].value,
clas_id=class_id,
stu_detail=sd,
)
stu_list.append(stu)
Student.objects.bulk_create(stu_list) # 批量创建学生
return redirect("/index/")

浙公网安备 33010602011771号