参考文章:
https://www.zhangshengrong.com/p/Z9a28xMkXV/
项目目录结构:

上传文件:
1、通用万精油模式:
settings 同级目录 urls:
from django.contrib import admin
from django.conf.urls import url,include
from middle import views
urlpatterns = [
url('admin/', admin.site.urls),
url(r'^middle/', include('middle.urls',namespace='middle')),
]
middle.urls:
from django.conf.urls import url
from middle import views
urlpatterns = [
url(r'^uploadfile', views.upload_file, name='upload_file'),
]
middle.views:
def upload_file(request):
if request.method == 'GET':
return render(request,'upload.html')
elif request.method == 'POST':
icon = request.FILES.get("icon")
with open("D:\project\django_introduction\static\img/1.jpg", "wb") as f:
for part in icon.chunks():
f.write(part)
return HttpResponse("文件上传成功")
templates.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>
<form action="{% url 'middle:upload_file' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<span>文件:</span>
<input type="file" name="icon">
<br>
<input type="submit" value="上传" >
</form>
</body>
</html>
2、使用框架模式:
settings:
# 新增
MEDIA_ROOT = os.path.join(BASE_DIR,'static/upload')
middle.models:
from django.db import models
class UserModel(models.Model):
u_name = models.CharField(max_length=16)
# upload_to 相对路径 相对于的是MEDIA_ROOT 媒体根目录
u_icon = models.ImageField(upload_to='icons')
# 记得!!!
# python manage.py makemigrations
# python manage.py migrate
middle.views:
def image_field(request):
if request.method == 'GET':
return render(request, 'image_field.html')
elif request.method == 'POST':
username = request.POST.get('username')
icon = request.FILES.get('icon')
user = UserModel()
user.u_username = username
user.u_icon = icon
user.save()
return HttpResponse("上传成功%d"%user.id)
# user. 后面会有其他方法,可以打印出来看
templates.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="{% url 'middle:image_field' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<span>用户名:</span><input type="text" name="username" placeholder="请输入用户名">
<br>
<span>头像:</span><input type="file" name="icon">
<br>
<button>上传</button>
</form>
</body>
</html>
上传图片之后,数据库数据格式,这里的 icons 就是模型中相对路径:

根据用户名获取图片:
middle.views:
def mine(request):
username = request.GET.get('username')
user = UserModel.objects.get(u_username=username)
icon_url = "/static/upload/" + user.u_icon.url
data = {"username": username,"icon_url": icon_url}
print(data)
return render(request,'mine.html',context=data)
templates.mine:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Mine</title>
</head>
<body>
<h3>{{ username }}</h3>
<img src="{{ icon_url }}" alt="{{ username }}">
</body>
</html>
发现问题:
- 1、上传的图都在一个文件夹下,不便于管理
- 2、容易出现文件重名
解决问题:
middle.models:
from django.db import models
import uuid
import os
def upload_to(instance, filename):
# 对文件进行重命名
filename = '{}.{}'.format(uuid.uuid4().hex[:10], filename.split('.')[-1])
return '/'.join([instance.u_username, filename])
class UserModel(models.Model):
u_username = models.CharField(max_length=16)
# upload_to 相对路径 相对于的是MEDIA_ROOT 媒体根目录
u_icon = models.ImageField(upload_to=upload_to)
- return ‘/’.join([instance.u_username, filename])
- return 出去的就是文件夹了
- 但是,之前我们获取的时候是根据 username 获取,现在不行了,只能根据id来获取了
views 修改传参:

html 修改参数:

下载文件:
# 下载图片/文件
def download(request):
if request.method == 'GET':
try:
# path = request.GET.get('path')
path = 'staticfiles/IDcardImg/1584431403.jpg'
with open(path,'rb') as f:
file = f.read()
response = HttpResponse(file)
# file_name下载下来保存的文件名字
file_name = path.split('/')[-1]
response['Content-Type'] = 'application/octet-stream'
response['Content-Disposition'] = 'attachment;filename={}'.format(file_name)
return response
except Exception as e:
print('error:',e)
return JsonResponse({'code':500,'msg':'服务端错误','error':'{}'.format(e)})
个人小记:万精油的上传,下载
上传文件:
# -*- coding:utf-8 -*-
# author: LIUWENYU
# contact: 1091761664@qq.com
# datetime: 2020/5/21 14:26
# software: PyCharm
# describe: 上传
from django.http.response import JsonResponse,HttpResponse
import time
import os
from wuliu import settings
# 上传图片/文件
def upload(request):
if request.method == "POST":
try:
# 接收文件
file = request.FILES['file'] # 上传的文件
folder = request.POST['folder'] # 文件夹
# print('folder:',folder)
# 判断是否有 file 和 folder
if not file and not folder:
return JsonResponse({'code':400,'msg':'缺少参数'})
# 限制文件大小
if file.size > 10485760:
return JsonResponse({'code':400,'msg':'请上传10MB以内的文件'})
# 设置允许上传的文件格式
ALLOW_EXTENSIONS = ['png', 'jpg', 'jpeg']
# 文件名
filename = str(time.time()).split(".")[0] + '.' + file.name.split(".")[-1]
# 图片路径
path = settings.BASE_DIR + '/static/' + folder + '/'
# 判断文件格式
if file.name.rsplit('.',1)[1].lower() in ALLOW_EXTENSIONS:
# 假如文件夹不存在,创建文件夹
if not os.path.exists(path):
os.makedirs(path)
else:
return JsonResponse({"code":400,'msg':'文件格式错误,请上传 png, jpg, jpeg'})
# print('path:', path)
# print('folder:',folder)
with open(path + filename, 'wb') as f:
# data = file.file.read() # 文件字节流数据 从文件中读取整个上传的数据。小心整个方法:如果这个文件很大,你把它读到内存中会弄慢你的系统。
# f.write(data)
for buf in file.chunks(): # 如果上传的文件足够大需要分块就返回真。默认的这个值是2.5M,当然这个值是可以调节的
f.write(buf)
url = '/' + folder + '/' + filename
return JsonResponse({'code': 0, 'msg': '上传成功', 'url': url})
except Exception as e:
print('error:', e)
return JsonResponse({'code': 500, 'msg':'服务端错误','error':'{}'.format(e)})
下载文件:
import os
from django.http.response import JsonResponse,HttpResponse
from django.utils.encoding import escape_uri_path
# 下载图片/文件
def download(path):
try:
path = path
if not os.path.exists(path):
return JsonResponse({'code':400,'msg':'文件不存在'},json_dumps_params={'ensure_ascii':False})
print('path:',path)
# path = 'staticfiles/IDcardImg/1584431403.jpg'
with open(path,'rb') as f:
file = f.read()
response = HttpResponse(file)
# file_name下载下来保存的文件名字
file_name = path.split('/')[-1]
print('file_name:',file_name)
response['Content-Type'] = 'application/octet-stream'
response['Content-Disposition'] = "attachment;filename={}".format(escape_uri_path(file_name)) # 处理中文乱码
return response
except Exception as e:
print('error:',e)
return JsonResponse({'code':500,'msg':'服务端错误','error':'{}'.format(e)})
可以修改参考,上面方法占内存:

本文详细介绍Django框架下文件上传及下载的两种主要模式:通用万精油模式和使用框架模式。涵盖上传流程、数据库存储策略、文件路径管理及下载功能实现。
6765

被折叠的 条评论
为什么被折叠?



