08 Django - Django媒体文件静态文件文件上传

news/2024/12/26 14:35:04/

九、Django媒体文件&静态文件&文件上传

1.静态文件和媒体文件

  • 媒体文件: 用户上传的文件, 叫做media
  • 静态文件: 存放在服务器的 css, js, image等,叫做static
在Django中使用静态文件
  • {% static 'img/example.jpg' %} => static模板关键字就是在settings.py中指定的静态文件夹中(应用下的static文件夹和STATICFILES_DIR寻找到符合条件的静态文件
  • 然后将相对路径写入html标签中
  • 注意: 应用下的static文件夹里的文件(包括STATICFILES_DIR下的文件) 似乎在网站生成时都统一放在了http://127.0.0.1:8000/static/
python"> 首先确保django.contrib.staticfiles在INSTELLED_APPS中
2) 在 setting.py中定义 SRARIC_URLSTATIC_URL = '/static/'
3) 在你的app的static目录中存放静态文件,比如APP/ static/ example.jpg
4) 如果有别的静态文件,不在app的static目录下,可以通过 STATICFILES_DIRS来指定额外的静态搜索目录STATICFILES_DIR = [os.path.join(BASE_DIR, 'static'),...]
5) 在模板中使用load标签去加载文件{% load static %}<img src="/static/index.css" /><img src="{% static 'img/example.jpg' %}" />
django_30">在django中使用媒体文件

在settings中配置 MEDIA_ROOT, 就是指定文件上传的路径选项

python">MEDIA_ROOT = os.path.join(BASE_DIR,"media")

2. 文件上传

单文件上传
python">文件上传要求form表单存在enctype="multipart/form-data"属性,并且提交方法是post。<form enctype="multipart/form-data" action="/uploadFile/" method="post"><input type="file" name="myfile" /><br/><input type="submit" value="upload"/></form>最简单的文件上传:
def file_upload(request):if request.method =='POST':# 获取上传的文件,如果没有文件,则默认为NonemyFile = request.FILES.get('myfile', None)if not myFile:return HttpResponse("no files for upload")file_path = os.path.join(settings.MEDIA_ROOT, '1.jpg')with open(file_path, 'ab') as fp:for part in myFile.chunks():fp.write(part)return HttpResponse("上传成功!")else:return render(request, 'index.html')
单文件上传案例

views.py

python">import os
import uuid
from django.conf import settings
from django.shortcuts import redirect, render
from django.urls import reverse
from App.models import *
# Create your views here.def index(request):return render(request, 'index.html')def index2(request):return render(request, 'index2.html')# 单文件上传
def upload1(request):if request.method == 'GET':return render(request, 'upload1.html')elif request.method == 'POST':# 单文件上传uname = request.POST.get('uname')icon = request.FILES.get('icon') # 单个文件print(uname, icon, type(icon))# 1.将上传的图片存储到后台对应的媒体文件中# file_name = icon.name   # 尽量不要使用图片的原始名称, 避免重复  # file_name = get_uuid() + icon.name[icon.name.rfind('.'):] # 获取后缀名file_name = get_uuid() + os.path.splitext(icon.name)[-1] # 获取后缀名file_path = os.path.join(settings.MEDIA_ROOT , file_name)print(file_path)with open(file_path, 'wb') as f:for chunk in icon.chunks(): # 分块写入f.write(chunk)f.flush()  # 立即写入# 2.将该媒体文件的路径,存入到数据库user = UserModel()user.name = unameuser.icon = 'uploads/' + file_name # 注意: 存储的是相对路径, 而不是绝对路径,相对于static的路径user.save()return render(request, 'upload1.html')# 获取uuid, 用于生成唯一的文件名
def get_uuid():return str(uuid.uuid4())def showicon(request, uid):if uid == None: # 如果没有传uid, 则默认为1uid = 1# 显示用户的头像user = UserModel.objects.filter(id=uid).first()print(user, user.name, user.icon)return render(request, 'showicon.html', {'user': user})    # 多文件上传
def upload2(request):if request.method == 'GET':return render(request, 'upload2.html')elif request.method == 'POST':# 接收前端的参数uname = request.POST.get('uname')uid = UserModel.objects.filter(name=uname).first().idimgs = request.FILES.getlist('imgs') # 多个文件print(uname, imgs, type(imgs))# [<InMemoryUploadedFile: chapter11_主界面.png (image/png)>, <InMemoryUploadedFile: chapter12_对话框.png (image/png)>] <class 'list'># 遍历文件列表, 依次上传for img in imgs:# 1.将上传的图片存储到后台对应的媒体文件中file_name = get_uuid() + os.path.splitext(img.name)[-1] # 获取后缀名file_path = os.path.join(settings.MEDIA_ROOT, file_name)with open(file_path, 'wb') as f:for chunk in img.chunks(): # 分块写入f.write(chunk)f.flush()  # 立即写入# 2.将该媒体文件的路径,存入到数据库photo = PhotoModel()photo.img = 'uploads/' + file_namephoto.user = UserModel.objects.filter(name=uname).first()photo.save()return redirect(reverse('showicon',kwargs={'uid': uid}))

settings.py

python">STATIC_URL = 'static/'
STATICFILES_DIRS = [BASE_DIR / 'static'
]
MEDIA_ROOT = BASE_DIR /'static/uploads'

models.py

python">from django.db import models# Create your models here.class UserModel(models.Model):name = models.CharField(max_length=32, unique=True)# 头像(存储头像的路径)icon = models.CharField(max_length=128)

upload1.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>单文件上传</title>
</head>
<body><form action="" method="post" enctype="multipart/form-data">{% csrf_token %}<p>用户名: <input type="text" name='uname'></p><p>头像: <input type="file" name="icon"></p><button>上传</button></form>
</body>
</html>

showicon.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>显示图标</title>
</head>
<body><h1>显示图标</h1><hr>{% load static  %}<p>{{user.name}}</p><img src="{% static user.icon %}" alt="">
</body>
</html>
多文件上传
python">多文件上传和单文件上传类似
1.需要在模板文件的form表单input中添加multiple
2.后台获取时使用request.FILES.getlist('myfile', None)
def file_upload2(request):if request.method == 'POST':# 获取上传的文件,如果没有文件,则默认为NonemyFiles = request.FILES.getlist('myfile', None)for myFile in myFiles:if not myFile:return HttpResponse("no files for upload")file_path = os.path.join(settings.MEDIA_ROOT, myFile.name)with open(file_path, 'ab') as fp:for part in myFile.chunks():fp.write(part)return HttpResponse("上传成功!")else:return render(request, 'index.html')
多文件上传案例

views.py

python">import os
import uuid
from django.conf import settings
from django.shortcuts import redirect, render
from django.urls import reverse
from App.models import *
# Create your views here.def index(request):return render(request, 'index.html')def index2(request):return render(request, 'index2.html')# 单文件上传
def upload1(request):if request.method == 'GET':return render(request, 'upload1.html')elif request.method == 'POST':# 单文件上传uname = request.POST.get('uname')icon = request.FILES.get('icon') # 单个文件print(uname, icon, type(icon))# 1.将上传的图片存储到后台对应的媒体文件中# file_name = icon.name   # 尽量不要使用图片的原始名称, 避免重复  # file_name = get_uuid() + icon.name[icon.name.rfind('.'):] # 获取后缀名file_name = get_uuid() + os.path.splitext(icon.name)[-1] # 获取后缀名file_path = os.path.join(settings.MEDIA_ROOT , file_name)print(file_path)with open(file_path, 'wb') as f:for chunk in icon.chunks(): # 分块写入f.write(chunk)f.flush()  # 立即写入# 2.将该媒体文件的路径,存入到数据库user = UserModel()user.name = unameuser.icon = 'uploads/' + file_name # 注意: 存储的是相对路径, 而不是绝对路径,相对于static的路径user.save()return render(request, 'upload1.html')# 获取uuid, 用于生成唯一的文件名
def get_uuid():return str(uuid.uuid4())def showicon(request, uid):if uid == None: # 如果没有传uid, 则默认为1uid = 1# 显示用户的头像user = UserModel.objects.filter(id=uid).first()print(user, user.name, user.icon)return render(request, 'showicon.html', {'user': user})    # 多文件上传
def upload2(request):if request.method == 'GET':return render(request, 'upload2.html')elif request.method == 'POST':# 接收前端的参数uname = request.POST.get('uname')uid = UserModel.objects.filter(name=uname).first().idimgs = request.FILES.getlist('imgs') # 多个文件print(uname, imgs, type(imgs))# [<InMemoryUploadedFile: chapter11_主界面.png (image/png)>, <InMemoryUploadedFile: chapter12_对话框.png (image/png)>] <class 'list'># 遍历文件列表, 依次上传for img in imgs:# 1.将上传的图片存储到后台对应的媒体文件中file_name = get_uuid() + os.path.splitext(img.name)[-1] # 获取后缀名file_path = os.path.join(settings.MEDIA_ROOT, file_name)with open(file_path, 'wb') as f:for chunk in img.chunks(): # 分块写入f.write(chunk)f.flush()  # 立即写入# 2.将该媒体文件的路径,存入到数据库photo = PhotoModel()photo.img = 'uploads/' + file_namephoto.user = UserModel.objects.filter(name=uname).first()photo.save()return redirect(reverse('showicon',kwargs={'uid': uid}))

upload2.html文件多选 -> multiple

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>多文件上传</title>
</head>
<body>{% comment %} multipart/form-data支持文件上传 {% endcomment %}{% comment %} multiple: 支持文件多选 {% endcomment %}<form action="" method="post" enctype="multipart/form-data">{% csrf_token %}<p>用户名: <input type="text" name='uname'></p><p>选择上传的图片: <input type="file" name="imgs" multiple></p><button>上传</button></form>
</body>
</html>

showicon.html添加

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>显示图标</title>
</head>
<body><h1>显示图标</h1><hr>{% load static  %}<p>{{user.name}}</p><p>头像<img src="{% static user.icon %}" alt=""></p><hr><h3>{{user.name}}的相册</h3>{% for photo in user.photomodel_set.all  %}<img src="{% static photo.img %}" alt="" width=100>{% endfor %}</body>
</html>

http://www.ppmy.cn/news/1558288.html

相关文章

Selenium 和 Playwright两大框架的不同之处

自动化测试工具百花齐放&#xff0c;其中 Selenium 和 Playwright 是两大热门框架&#xff0c;谁才是你的最佳选择&#xff1f;面对企业项目的真实需求&#xff0c;它们的差异究竟在哪儿&#xff1f; Selenium 和 Playwright 是两种流行的自动化测试工具&#xff0c;它们都被用…

PR基础(2)

上一篇分享了影视后期软件中的PR的一些基础使用&#xff0c;包括序列、工具栏、简单视频拼接&#xff0c;本篇将继续讲解记录其他的基础使用。 废话不多说。 新建项 子项目 pr 软件中在 “新建项”按钮选项中有一个“项目快捷方式”&#xff0c;就是创建我们认知意义上的子项…

springboot492基于java线上历史馆藏系统(论文+源码)_kaic

摘 要 计算机网络发展到现在已经好几十年了&#xff0c;在理论上面已经有了很丰富的基础&#xff0c;并且在现实生活中也到处都在使用&#xff0c;可以说&#xff0c;经过几十年的发展&#xff0c;互联网技术已经把地域信息的隔阂给消除了&#xff0c;让整个世界都可以即时通话…

Opencv实现图像的腐蚀、膨胀及开、闭运算

图像的腐蚀、膨胀及开闭运算 目录 图像的腐蚀、膨胀及开闭运算图像的腐蚀、膨胀图像的腐蚀图像的膨胀 图像的开、闭运算图像的开运算图像的闭运算 图像的腐蚀、膨胀 图像的腐蚀 概念&#xff1a;将图像中的高亮区域或白色部分进行缩减细化&#xff0c;其运行结果图比原图的高亮…

科技快讯 | 刘强东提前发年终奖;理想超充站超时占用费试运营;美团听障骑手助手全量上线;微信视频号评论区可以斗图了

刘强东提前发年终奖 京东集团宣布&#xff0c;O序列员工将于1月26日&#xff0c;P序列员工将于2月27日收到2024年年终奖。年终奖结构升级为固定年终奖加目标年终奖&#xff0c;其中A级员工年终奖为8倍月薪。采销员工年终奖已于7月升级&#xff0c;2024年年终奖平均23薪&#xf…

MySQL45讲 第三十六讲 为什么临时表可以重名?——阅读总结

文章目录 MySQL45讲 第三十六讲 为什么临时表可以重名&#xff1f;——阅读总结一、引言二、临时表与内存表的区别&#xff08;一&#xff09;内存表&#xff08;二&#xff09;临时表 三、临时表的特性&#xff08;一&#xff09;可见性与生命周期&#xff08;二&#xff09;与…

AI应用-本地模型实现AI生成PPT(简易版)

文章目录 前言技术栈效果展示 一、实现思路二、实现步骤1.本地安装marp-cli2.后端实现3.前端实现 三、代码地址及说明 前言 在许多项目中&#xff0c;生成 PPT 是常见的需求&#xff0c;尤其在教育和报告展示中。传统的生成 PPT 的方法需要手动创建&#xff0c;而使用生成模型…

【微信小程序】3|首页搜索框 | 我的咖啡店-综合实训

首页-搜索框-跳转 引言 在微信小程序中&#xff0c;首页的搜索框是用户交互的重要入口。本文将通过“我的咖啡店”小程序的首页搜索框实现&#xff0c;详细介绍如何在微信小程序中创建和处理搜索框的交互。 1. 搜索函数实现 onClickInput函数在用户点击搜索框时触发&#x…