初识Django之静态资源文件上传
准备工作
在setings.py中加上注册地址
- 静态文件地址STATICFILES_DIRS,可以通过static路径访问静态资源。
1
2
3STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
] - 图片上传存储地址MEDIA_ROOT
1
MEDIA_ROOT = os.path.join(BASE_DIR, 'static/upload')
文件上传
基础方法
上传界面,对文件进行分包加密enctype=”multipart/form-data”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>
<form action="{% url 'app:upload_file' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<span>文件:</span>
<input type="file" name="icon">
<br>
<input type="submit" value="上传">
</form>
</body>
</html>后台接收,以固定的地址和固定的名称进行存储,通过chunks方法一块块接收,并写入。
1
2
3
4
5
6
7
8
9
10
11def upload_file(request):
if request.method == "GET":
return render(request, 'upload.html')
elif request.method == "POST":
icon = request.FILES.get("icon")
print(icon, type(icon))
with open("static/img/icon.png", 'wb') as save_file:
for part in icon.chunks():
save_file.write(part)
save_file.flush()
return HttpResponse("文件上传成功")
进阶方法
- 在models.py 创建对应类
在过程中需要安装pillow依赖pip install pillow
Linux中一个文件夹中文件存储上限65535,会打不开文件夹。
所以在upload_to中以年月日进行存储,这样就不会一直存储在一个文件夹中。1
2
3
4
5class UserModel(models.Model):
u_name = models.CharField(max_length=16)
# upload_to 相对路径 相对于的是MEDIA_ROOT 媒体根目录
# u_icon = models.ImageField(upload_to="icons") 指定icons目录
u_icon = models.ImageField(upload_to="%Y/%m/%d/icons") # 根据时间进行分开存储 - 上传界面与上面无差别
- 后台接收
直接调用UserModel,然后赋值存储。同名的文件会自动加尾缀重命名。1
2
3
4
5
6
7
8
9
10
11
12def image_field(request):
if request.method == "GET":
return render(request, 'image_field.html')
elif request.method == "POST":
username = request.POST.get("username")
icon = request.FILES.get("icon")
user = UserModel()
user.u_name = username
user.u_icon = icon
user.save()
return HttpResponse('上传成功%d' % user.id)
遇到的问题
1. context must be a dict rather than set.
在获取个人信息时,往context中传入data时,简写并不适用。如下,定义了用户名和用户头像。
1 | username = request.GET.get("username") |
- 错误写法:
1
2
3
4
5data = {
username,
icon_url
}
return render(request, "mine.html", context=data) - 正确写法:
1
2
3
4
5data = {
'username': username,
'icon_url': icon_url
}
return render(request, "mine.html", context=data)
2. request.Files.get获取不到文件
在上面获取图片内容时request.FILES.get(“icon”)一直为NoneType,获取不到对应的图片信息。
表单中的name是否和get中参数对应
1
<input type="file" name="icon">
表单没有填写 enctype=”multipart/form-data”
1
2
3
4
5
6
7<form action="{% url 'app:upload_file' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<span>文件:</span>
<input type="file" name="icon">
<br>
<input type="submit" value="上传">
</form>
3. expected str, bytes or os.PathLike object, not list
由于自己对django的基础掌握不是很牢固,忽略了MEDIA_ROOT的类型是string,而不是list。
- 错误写法:
1
2
3MEDIA_ROOT = [
os.path.join(BASE_DIR, 'static/upload'),
] - 正确写法:
1
MEDIA_ROOT = os.path.join(BASE_DIR, 'static/upload')
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 随心所欲录!
评论