当前位置: 首页 > article >正文

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

九、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>

http://www.kler.cn/a/452284.html

相关文章:

  • Linux:SystemV通信
  • “乡村探索者”:村旅游网站的移动应用开发
  • cannot import name ‘_C‘ from ‘pytorch3d‘
  • Spring Boot对访问密钥加解密——HMAC-SHA256
  • 强力巨彩租赁屏技术更新,适用多种户外应用场景
  • 代码随想录Day37 动态规划:完全背包理论基础,518.零钱兑换II,本周小结动态规划,377. 组合总和 Ⅳ,70. 爬楼梯(进阶版)。
  • Ubuntu存储硬盘扩容-无脑ChatGPT方法
  • 嵌入式学习-QT-Day06
  • 网站使用站群服务器都有哪些好处?
  • Vue学习手册03 Vue虚拟DOM详解
  • mysql,数据库主从同步搭建
  • 帝国cms电脑pc站url跳转到手机站url的方法
  • 20241225在ubuntu22.04.5下使用smartmontools命令查看ssd的寿命
  • Diffusers使用笔记
  • 2024年河北省职业院校技能大赛云计算应用赛项赛题第2套(容器云)
  • 从tryLock()源码来出发,解析Redisson的重试机制和看门狗机制
  • 2024年OpenTiny年度人气贡献者评选正式开始
  • MFC用List Control 和Picture控件实现界面切换效果
  • leetcode hot100 翻转二叉树
  • golang实现yaml配置文件的解析
  • DVWA靶场第三关 CSRF
  • 【jvm】内存泄漏与内存溢出的区别
  • [Python3] Sanic中间件
  • 你比AI更有价值吗?
  • 微信小程序-基于Vant Weapp UI 组件库的Area 省市区选择
  • ESLint (10)