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

打印 上一主题 下一主题

主题 1025|帖子 1025|积分 3075

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

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/下
  1. 首先确保django.contrib.staticfiles在INSTELLED_APPS中
  2. 2) 在 setting.py中定义 SRARIC_URL
  3.                 STATIC_URL = '/static/'
  4. 3) 在你的app的static目录中存放静态文件,比如
  5.                 APP/ static/ example.jpg
  6. 4) 如果有别的静态文件,不在app的static目录下,可以通过 STATICFILES_DIRS来指定额外的静态搜索目录
  7.                 STATICFILES_DIR = [
  8.             os.path.join(BASE_DIR, 'static'),
  9.             ...
  10.         ]
  11. 5) 在模板中使用load标签去加载文件
  12.                 {% load static %}
  13.             <img src="/static/index.css" />
  14.             <img src="{% static 'img/example.jpg' %}" />
复制代码
在django中利用媒体文件

在settings中设置 MEDIA_ROOT, 就是指定文件上传的路径选项
  1. MEDIA_ROOT = os.path.join(BASE_DIR,"media")
复制代码
2. 文件上传

单文件上传

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

views.py
  1. import os
  2. import uuid
  3. from django.conf import settings
  4. from django.shortcuts import redirect, render
  5. from django.urls import reverse
  6. from App.models import *
  7. # Create your views here.
  8. def index(request):
  9.     return render(request, 'index.html')
  10. def index2(request):
  11.     return render(request, 'index2.html')
  12. # 单文件上传
  13. def upload1(request):
  14.     if request.method == 'GET':
  15.         return render(request, 'upload1.html')
  16.     elif request.method == 'POST':
  17.         # 单文件上传
  18.         uname = request.POST.get('uname')
  19.         icon = request.FILES.get('icon') # 单个文件
  20.         print(uname, icon, type(icon))
  21.         # 1.将上传的图片存储到后台对应的媒体文件中
  22.         # file_name = icon.name   # 尽量不要使用图片的原始名称, 避免重复  
  23.         # file_name = get_uuid() + icon.name[icon.name.rfind('.'):] # 获取后缀名
  24.         file_name = get_uuid() + os.path.splitext(icon.name)[-1] # 获取后缀名
  25.         file_path = os.path.join(settings.MEDIA_ROOT , file_name)
  26.         print(file_path)
  27.         with open(file_path, 'wb') as f:
  28.             for chunk in icon.chunks(): # 分块写入
  29.                 f.write(chunk)
  30.                 f.flush()  # 立即写入
  31.         # 2.将该媒体文件的路径,存入到数据库中
  32.         user = UserModel()
  33.         user.name = uname
  34.         user.icon = 'uploads/' + file_name # 注意: 存储的是相对路径, 而不是绝对路径,相对于static的路径
  35.         user.save()
  36.         return render(request, 'upload1.html')
  37.    
  38. # 获取uuid, 用于生成唯一的文件名
  39. def get_uuid():
  40.     return str(uuid.uuid4())
  41. def showicon(request, uid):
  42.     if uid == None: # 如果没有传uid, 则默认为1
  43.         uid = 1
  44.     # 显示用户的头像
  45.     user = UserModel.objects.filter(id=uid).first()
  46.     print(user, user.name, user.icon)
  47.     return render(request, 'showicon.html', {'user': user})   
  48. # 多文件上传
  49. def upload2(request):
  50.     if request.method == 'GET':
  51.         return render(request, 'upload2.html')
  52.     elif request.method == 'POST':
  53.         # 接收前端的参数
  54.         uname = request.POST.get('uname')
  55.         uid = UserModel.objects.filter(name=uname).first().id
  56.         imgs = request.FILES.getlist('imgs') # 多个文件
  57.         print(uname, imgs, type(imgs))
  58.         # [<InMemoryUploadedFile: chapter11_主界面.png (image/png)>, <InMemoryUploadedFile: chapter12_对话框.png (image/png)>] <class 'list'>
  59.         # 遍历文件列表, 依次上传
  60.         for img in imgs:
  61.             # 1.将上传的图片存储到后台对应的媒体文件中
  62.             file_name = get_uuid() + os.path.splitext(img.name)[-1] # 获取后缀名
  63.             file_path = os.path.join(settings.MEDIA_ROOT, file_name)
  64.             with open(file_path, 'wb') as f:
  65.                 for chunk in img.chunks(): # 分块写入
  66.                     f.write(chunk)
  67.                     f.flush()  # 立即写入
  68.             # 2.将该媒体文件的路径,存入到数据库中
  69.             photo = PhotoModel()
  70.             photo.img = 'uploads/' + file_name
  71.             photo.user = UserModel.objects.filter(name=uname).first()
  72.             photo.save()
  73.         return redirect(reverse('showicon',kwargs={'uid': uid}))
复制代码
settings.py
  1. STATIC_URL = 'static/'
  2. STATICFILES_DIRS = [
  3.     BASE_DIR / 'static'
  4. ]
  5. MEDIA_ROOT = BASE_DIR /'static/uploads'
复制代码
models.py
  1. from django.db import models
  2. # Create your models here.
  3. class UserModel(models.Model):
  4.     name = models.CharField(max_length=32, unique=True)
  5.     # 头像(存储头像的路径)
  6.     icon = models.CharField(max_length=128)
复制代码
upload1.html
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>单文件上传</title>
  7. </head>
  8. <body>
  9.     <form action="" method="post" enctype="multipart/form-data">
  10.         {% csrf_token %}
  11.         <p>用户名: <input type="text" name='uname'></p>
  12.         <p>头像: <input type="file" name="icon"></p>
  13.         <button>上传</button>
  14.     </form>
  15. </body>
  16. </html>
复制代码
showicon.html
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>显示图标</title>
  7. </head>
  8. <body>
  9.     <h1>显示图标</h1>
  10.     <hr>
  11.     {% load static  %}
  12.     <p>{{user.name}}</p>
  13.     <img src="{% static user.icon %}" alt="">
  14. </body>
  15. </html>
复制代码
多文件上传

  1. 多文件上传和单文件上传类似
  2. 1.需要在模板文件的form表单input中添加multiple
  3. 2.后台获取时使用request.FILES.getlist('myfile', None)
  4. def file_upload2(request):
  5.     if request.method == 'POST':
  6.         # 获取上传的文件,如果没有文件,则默认为None
  7.         myFiles = request.FILES.getlist('myfile', None)
  8.         for myFile in myFiles:
  9.             if not myFile:
  10.                 return HttpResponse("no files for upload")
  11.             file_path = os.path.join(settings.MEDIA_ROOT, myFile.name)
  12.             with open(file_path, 'ab') as fp:
  13.                 for part in myFile.chunks():
  14.                     fp.write(part)
  15.                     return HttpResponse("上传成功!")
  16.                 else:
  17.                     return render(request, 'index.html')
复制代码
多文件上传案例

views.py
  1. import os
  2. import uuid
  3. from django.conf import settings
  4. from django.shortcuts import redirect, render
  5. from django.urls import reverse
  6. from App.models import *
  7. # Create your views here.
  8. def index(request):
  9.     return render(request, 'index.html')
  10. def index2(request):
  11.     return render(request, 'index2.html')
  12. # 单文件上传
  13. def upload1(request):
  14.     if request.method == 'GET':
  15.         return render(request, 'upload1.html')
  16.     elif request.method == 'POST':
  17.         # 单文件上传
  18.         uname = request.POST.get('uname')
  19.         icon = request.FILES.get('icon') # 单个文件
  20.         print(uname, icon, type(icon))
  21.         # 1.将上传的图片存储到后台对应的媒体文件中
  22.         # file_name = icon.name   # 尽量不要使用图片的原始名称, 避免重复  
  23.         # file_name = get_uuid() + icon.name[icon.name.rfind('.'):] # 获取后缀名
  24.         file_name = get_uuid() + os.path.splitext(icon.name)[-1] # 获取后缀名
  25.         file_path = os.path.join(settings.MEDIA_ROOT , file_name)
  26.         print(file_path)
  27.         with open(file_path, 'wb') as f:
  28.             for chunk in icon.chunks(): # 分块写入
  29.                 f.write(chunk)
  30.                 f.flush()  # 立即写入
  31.         # 2.将该媒体文件的路径,存入到数据库中
  32.         user = UserModel()
  33.         user.name = uname
  34.         user.icon = 'uploads/' + file_name # 注意: 存储的是相对路径, 而不是绝对路径,相对于static的路径
  35.         user.save()
  36.         return render(request, 'upload1.html')
  37.    
  38. # 获取uuid, 用于生成唯一的文件名
  39. def get_uuid():
  40.     return str(uuid.uuid4())
  41. def showicon(request, uid):
  42.     if uid == None: # 如果没有传uid, 则默认为1
  43.         uid = 1
  44.     # 显示用户的头像
  45.     user = UserModel.objects.filter(id=uid).first()
  46.     print(user, user.name, user.icon)
  47.     return render(request, 'showicon.html', {'user': user})   
  48. # 多文件上传
  49. def upload2(request):
  50.     if request.method == 'GET':
  51.         return render(request, 'upload2.html')
  52.     elif request.method == 'POST':
  53.         # 接收前端的参数
  54.         uname = request.POST.get('uname')
  55.         uid = UserModel.objects.filter(name=uname).first().id
  56.         imgs = request.FILES.getlist('imgs') # 多个文件
  57.         print(uname, imgs, type(imgs))
  58.         # [<InMemoryUploadedFile: chapter11_主界面.png (image/png)>, <InMemoryUploadedFile: chapter12_对话框.png (image/png)>] <class 'list'>
  59.         # 遍历文件列表, 依次上传
  60.         for img in imgs:
  61.             # 1.将上传的图片存储到后台对应的媒体文件中
  62.             file_name = get_uuid() + os.path.splitext(img.name)[-1] # 获取后缀名
  63.             file_path = os.path.join(settings.MEDIA_ROOT, file_name)
  64.             with open(file_path, 'wb') as f:
  65.                 for chunk in img.chunks(): # 分块写入
  66.                     f.write(chunk)
  67.                     f.flush()  # 立即写入
  68.             # 2.将该媒体文件的路径,存入到数据库中
  69.             photo = PhotoModel()
  70.             photo.img = 'uploads/' + file_name
  71.             photo.user = UserModel.objects.filter(name=uname).first()
  72.             photo.save()
  73.         return redirect(reverse('showicon',kwargs={'uid': uid}))
复制代码
upload2.html文件多选 -> multiple
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>多文件上传</title>
  7. </head>
  8. <body>
  9.     {% comment %} multipart/form-data支持文件上传 {% endcomment %}
  10.     {% comment %} multiple: 支持文件多选 {% endcomment %}
  11.     <form action="" method="post" enctype="multipart/form-data">
  12.         {% csrf_token %}
  13.         <p>用户名: <input type="text" name='uname'></p>
  14.         <p>选择上传的图片: <input type="file" name="imgs" multiple></p>
  15.         <button>上传</button>
  16.     </form>
  17. </body>
  18. </html>
复制代码
showicon.html添加
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>显示图标</title>
  7. </head>
  8. <body>
  9.     <h1>显示图标</h1>
  10.     <hr>
  11.     {% load static  %}
  12.     <p>{{user.name}}</p>
  13.     <p>头像<img src="{% static user.icon %}" alt=""></p>
  14.    
  15.     <hr>
  16.     <h3>{{user.name}}的相册</h3>
  17.     {% for photo in user.photomodel_set.all  %}
  18.     <img src="{% static photo.img %}" alt="" width=100>
  19.     {% endfor %}
  20. </body>
  21. </html>
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

南飓风

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表