一、Django文件上传基础
- 定义:通过浏览器将图片等文件上传至服务器数据库中
- 场景:上传文件(图片、文档、视频等)
1.1 文件上传注意事项
- 存储上传文件的地址:按照文件类型分类,并以时间来创建文件夹命名,避免覆盖上传文件
- 上传文件命名:以言简意赅为命名
- 可接受的文件类型进行限制:文件类型、大小等
1.2 上传规范–前端
- 文件上传必须用
POST
提交方式 - 表单
<form>
中文件上传必须带有enctype="multipart/form-data"
时才会包含文件内容数据,即修改form
的content-type
- 表单中用
<input type="file" name="xxx">
标签上传文件
1.3 上传规范–后端
- 视图函数中,不能再用
request.POST.get("name")
文件框的内容了,需要使用file=request.FILES.get("name")
取值
序号 | 参数 | 说明 |
---|---|---|
1 | file = request.FILES.get(name) | 获取文件流对象 |
2 | file.name | 获取文件名 |
3 | file.file | 获取文件的字节流数据 |
配置文件的访问路径与存储位置(类似于静态文件的效果)
- 在
settings.py
中设置MEDIA相关配置;Django把用户上传的文件,统称为media资源。
# file:settings.py
MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(BASE_DIR,'media')
# 类似于静态文件的配置
MEDIA_URL
与MEDIA_ROOT
需要手动绑定才能生效
# 主urls.py中添加配置
from django.contrib import admin
from django.urls import path
urlpatterns = [
path('admin/', admin.site.urls),
]
from django.conf import settings
from django.conf.urls.static import static
urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
说明: 等价于做了MEDIA_URL
开头的路由,类似于静态文件的路由,Django接到该特征请求后去MEDIA_ROOT
路径查找资源
二、文件重命名
- 以时间和随机字符集来重命名
import random
import datetime
def file_rename(file_name):
# 65-90:A-Z;97-122:a-z;48-57:0-9,通过ASCLL来创建你随机字符集
character_set = [chr(i) for i in list(range(65, 91)) + list(range(97, 123)) + list(range(48, 58))]
# 获取当前时间:20210720
time_now = datetime.datetime.strftime(datetime.datetime.now(),'%Y%m%d')
# 获取当前时间戳:1626747222
# time_now = int(datetime.datetime.timestamp(datetime.datetime.now()))
# 随机选取的字符集子集
alias = "".join(random.sample(character_set, 10))
if "." in name:
rename = f"{time_now}{alias}.{file_name.split('.')[-1]}"
else:
rename = f"{time_now}{alias}"
return rename
print(file_rename("AAA.csv"))
print(file_rename("BBB"))
20210720aJz1M7ZwET.csv
20210720Ncdz41oqEJ
三、Django文件上传
3.1、基于form表单的文件上传
- 前端利用
form
表单实现文件上传,后端采用open
法写入并保存到相应的位置 - 缺点:文件大小,类型等验证不方便,读取不方便,无数据库索引等问题
def file_up(request):
if request.method == "GET":
return render(request,"file_up.html")
elif request.method == "POST":
file = request.FILES.get("file")
print(f"文件上传的文件名为:{file.name},文件大小为:{file.file}")
# 判断是否有重命名情况
if file.name in os.listdir(settings.MEDIA_ROOT):
filename = os.path.join(settings.MEDIA_ROOT,str(random.randint(0,100)*random.randint(0,100)-random.randint(0,5))+file.name)
else:
filename = os.path.join(settings.MEDIA_ROOT, file.name)
print(f"文件所在地址为:{filename}")
with open(filename,'wb') as f:
f.write(file.file.read())
return HttpResponse("文件上传成功!")
3.2、基于forms组件的文件上传
- 基于
django
的forms
组件实现文件上传,较为优于前面一种,便于添加一些表单验证 - 缺点:读取不方便,无数据库索引等问题;方便了上传文件的一些限制
from django.shortcuts import render,redirect,HttpResponse
from django.forms import forms
import os
from django.views.decorators.csrf import csrf_exempt
# 用forms组件来创建一个表单类,这里可以添加一些文件验证如文件大小、类型
class FileUploadForm(forms.Form):
file = forms.FileField(label="文件上传")
def handle_uploaded_file(f):
save_path = os.path.join('./media/', f.name)
with open(save_path, 'wb+') as fp:
for chunk in f.chunks():
fp.write(chunk)
@csrf_exempt
def file_upload(request, *args, **kwargs):
error_msg = ""
if request.method == 'POST':
forms = FileUploadForm(request.POST,request.FILES)
if forms.is_valid():
handle_uploaded_file(request.FILES['file'])
return HttpResponse('上传成功')
error_msg = "异常"
else:
forms = FileUploadForm()
return render(request,'index.html',{'forms':forms, "error_msg": error_msg})
3.3 ORM模型上传
- step1:设置文件保存的模型(表结构)
这个属性提供了一种设置上传目录和文件名的方式,可以有两种设置方式。在这两种情况下,值都会传递给 Storage.save()
方法。如果你指定一个字符串值或一个 Path
,它可能包含 strftime()
格式,它将被文件上传的日期/时间所代替(这样上传的文件就不会填满指定的目录)。例如:
# file:models.py
class MyModel(models.Model):
# file will be uploaded to MEDIA_ROOT/uploads
upload = models.FileField(upload_to='uploads/')
# or...
# file will be saved to MEDIA_ROOT/uploads/2015/01/30
upload = models.FileField(upload_to='uploads/%Y/%m/%d/')
- step2:设置将文件保存至表中
def file_up(request):
if request.method == "GET":
return render(request, "file_up.html")
elif request.method == "POST":
file = request.FILES.get("file")
title = request.POST.get("title")
Content.objects.create(title=title,picture=file)
return HttpResponse("文件上传成功")
文件的访问
- 直接输入网址:http://127.0.0.1:8000/media/picture/a.jpg

Python生成CSV文件
import csv
# w只写模式,newline=‘’指的是特殊符号不会进行转义
with open("exp.csv",'w',newline='') as f_csv:
writer = csv.writer(f_csv)
writer.writerows(['1','2','3'],) # 参数为一个列表,调用一次写一行
writer.writerow(['a','b','c']) # 参数为一个列表,调用一次写一行
print("执行结束")
CSV文件下载
网页中,如何实现csv下载:
- 响应Content-Type类型需要修改为text/csv。告诉浏览器该文档是csv文件,而不是HTML文件。
- 响应会获得一个额外的Content-Disposition标头,其中包含了csv文件的名称,它将被浏览器用于开启,另存为对话框。
# appname/views.py
from django.shortcuts import render,HttpResponse
import csv
# Create your views here.
def test_csv(request):
# 1.修改响应类型为csv
response = HttpResponse(content_type='text/csv')
# 2.在响应里面添加特殊的响应头,添加文件名
response['Content-Disposition'] = 'attachment;filename="test.csv"'
# 3.准备数据
data = list(range(10))
# 4.调用csv.writer,并直接指向响应对象
writer = csv.writer(response)
# 5.写入数据
writer.writerow(data)
return response
- https://www.cnblogs.com/fu-yong/p/8831218.html