马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
九、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/下
- 首先确保django.contrib.staticfiles在INSTELLED_APPS中
- 2) 在 setting.py中定义 SRARIC_URL
- STATIC_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中利用媒体文件
在settings中设置 MEDIA_ROOT, 就是指定文件上传的路径选项
- MEDIA_ROOT = os.path.join(BASE_DIR,"media")
复制代码 2. 文件上传
单文件上传
- 文件上传要求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':
- # 获取上传的文件,如果没有文件,则默认为None
- myFile = 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
- 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 = uname
- user.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, 则默认为1
- uid = 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().id
- imgs = 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_name
- photo.user = UserModel.objects.filter(name=uname).first()
- photo.save()
- return redirect(reverse('showicon',kwargs={'uid': uid}))
复制代码 settings.py
- STATIC_URL = 'static/'
- STATICFILES_DIRS = [
- BASE_DIR / 'static'
- ]
- MEDIA_ROOT = BASE_DIR /'static/uploads'
复制代码 models.py
- 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>
复制代码 多文件上传
- 多文件上传和单文件上传类似
- 1.需要在模板文件的form表单input中添加multiple
- 2.后台获取时使用request.FILES.getlist('myfile', None)
- def file_upload2(request):
- if request.method == 'POST':
- # 获取上传的文件,如果没有文件,则默认为None
- myFiles = 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
- 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 = uname
- user.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, 则默认为1
- uid = 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().id
- imgs = 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_name
- photo.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>
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |