django练手(十六):增加一个上传图标的功能

一.在settings.py 中配置MEDIA_ROOT

这个动作的作用是告诉django,上传的文件的根目录是那个。具体的操作方式是:在setting.py的最后一行加上代码:MEDIA_ROOT = BASE_DIR/'uploads'

二.配置上传模板

在app-templates-app文件夹下新建一个html文件,命名为user_info.html,作为上传文件的模板。
模板的代码如下:

{% extends 'app/layout/basic.html' %}
{% block content %}
<!--
上传文件的form。
action:后台的地址;
method:发送的方式。上传文件一般用post方式发送;
enctype:即encode type的缩写。意思是编码方式。 multipart/form-data 代表form数据有多种编码方式。
-->
<form name="file" method="post" action="{% url 'app:avatar_upload' %}" enctype="multipart/form-data" id="form_upload">
{% csrf_token %}
    <!--
    上传文件的input标签。
    type的参数必须是file,代表上传文件。
    accept表示允许上传的文件类型。"image/*"代表所用图片类型。
    multiple 表示一次可以传多个文件。没有这个参数一次只能上传一个文件。
    required 表示在提交前必须选择一个文件
    -->
    <input type="file"  accept="image/*" name="avatar_upload" id="input_upload" multiple required>
    <input type="submit" value="上传" class="btn btn-default btn-custom" id="btn_upload">
</form>

{% endblock %}

三.设计一个数据表,用来存储上传图标的名字,地址,上传时间

# 用户图标上传模型
class Avatar(models.Model):
	# 图标名称
	title = models.CharField(max_length=30, verbose_name='图片名称', help_text='图片名称,超过30个字会被截断')
	# 上传时间
	time = models.DateTimeField(auto_now_add=True, help_text='图片上传时间')
	# 图片路径
	img_url = models.CharField(max_length=300, verbose_name='图片路径')

四.设计一个视图,用来接收用户上传的图标,并进行处理

功能说明:
1、不登录不能访问该视图。
2、接收用户上传的图标。
3、判断存储图标的文件路径是否存在,如果不存在则创建路径。
4、把图标按路径存在硬盘。
5、把图片信息存储在数据库中。

视图代码的位置在:app-views-app-account.py (这个文件是原来views.py重命名得来得,用来存放与账号相关得视图)
以下是代码:

# 图标上传
@login_required
def avatar_upload(request):
	if request.method == 'get':
		return render(request, 'app/user_info.html')
	if request.method == "POST":
		# 1、判断文件路径是否存在,如果不存在,生成文件路径。
		image_folder_path = os.path.join(settings.MEDIA_ROOT, 'image', 'avatar')  # 文件路径
		image_folder_path_exists = os.path.exists(image_folder_path)  # 判断文件路径是否存在
		# 如果不存在,则生成文件路径
		if not image_folder_path_exists:
			os.makedirs(image_folder_path)
		# 获取所有上传的图标
		file_list = request.FILES.getlist('avatar_upload', '')
		if file_list:
			for file in file_list:
				# 1、把文件名替换成整个系统唯一的文件名。其中,uuid_name是我设计的一个小工具。这个工具的源码见第六部分。
				name = uuid_name(file.name)
				# 2、获取文件中文名
				title = os.path.splitext(file.name)[0]
				# 3、文件存储的位置。
				file_path = image_folder_path + '\\' + name
				# 4、把文件写入硬盘
				with open(file_path, 'wb', ) as f:
					for part in file.chunks():
						f.write(part)  # 内容块写入文件
						f.flush()  # 清除内存
				# 5、生成存储在数据库里的路径。
				database_path = 'uploads/image/avatar/' + name
				# 6、把文件信息写入数据库
				avatar = Avatar()
				avatar.title = title
				avatar.img_url = database_path
				avatar.save()
	return render(request, 'app/user_info.html')

五.上传图标的路由配置

路由文件位置:app-urls.py
路由的代码如下:

from django.urls import path
from app.views.app.account import *

urlpatterns = [
	path('register/', register, name='register'),  # 注册的路由
	path('login/', login_view, name='login'),  # 登录的路由
	path('logout/', auth_logout, name='logout'),  # 注销的路由
	path('changepwd/', change_password, name='change_password'),  # 修改密码的路由
	path('avatar/',avatar_upload,name='avatar_upload'), # 用户图标上传
]

六.给文件唯一命名的小程序

为了防止重名文件覆盖,用户上传的图标名称必须唯一。为此,我使用UUID设计了一个重新命名的小工具。
这个小工具在项目中的位置在:app-untils-rename.py
代码如下:

import uuid
import os


def uuid_name(name):
	"""
	1、传进来一个带后缀的文件名,并获取这个文件名的后缀。
	2、获取一个uuid4,并把它转换成字符串。
	3、uuid4字符串和文件名后缀拼接成一个新的文件名,并把这个文件名返回去。
	4、因为uuid是整个系统唯一的,所以这个新文件名也是系统唯一的。
	"""
	new_name = str(uuid.uuid4()) + os.path.splitext(name)[-1]
	return new_name
posted @ 2024-01-06 12:26  喜气洋洋白云山  阅读(35)  评论(0编辑  收藏  举报