Django 高级实战编程
Django高级实战 开发企业级问答网站
项目结合:需求分析/Django高级用法/算法/设计模式/TestCase测试/云计算服务
Django开发企业实战 面向就业/升职(中高级教程)
视频教程分享地址:
https://study.163.com/course/introduction/1209407824.htm?share=2&shareId=400000000535031
Django默认使用的文件存储系统 django.core.files.storage.FileSystemStorage
是一个本地存储系统,由settings
中的DEFAULT_FILE_STORAGE
值确定。
class FileSystemStorage(location=None, base_url=None, file_permissions_mode=None, directory_permissions_mode=None)
FileSystemStorage
类继承自Storage类
,location
是存储文件的绝对路径,默认值是settings
中的MEDIA_ROOT
值,base_url
默认值是settings
中的MEDIA_URL
值。
当定义location
参数时,可以无视MEDIA_ROOT
值来存储文件:
from django.db import models
from django.core.files.storage import FileSystemStorage
fs = FileSystemStorage(location='/media/photos')
class Car(models.Model):
...
photo = models.ImageField(storage=fs)
这样文件会存储在/media/photos
文件夹。
可以直接使用Django的文件存储系统来存储文件:
>>> from django.core.files.storage import default_storage
>>> from django.core.files.base import ContentFile
>>> path = default_storage.save('/path/to/file', ContentFile('new content'))
>>> path
'/path/to/file'
>>> default_storage.size(path)
11
>>> default_storage.open(path).read()
'new content'
>>> default_storage.delete(path)
>>> default_storage.exists(path)
False
方法中可以看出,先判断文件存储的目录是否存在,如果不存在,使用os.mkdirs()依次创建目录。
根据directory_permissions_mode参数来确定创建的目录的权限,应该为(0777 &~umask)。
然后使用os.open()创建文件,flags参数为(os.O_WRONLY | os.O_CREAT | os.O_EXCL | getattr(os, ‘O_BINARY’, 0)),
这样当文件已存在时,则报EEXIST异常,使用get_available_name()方法重新确定文件的名字。
mode为0o666,权限为(0666 &~umask)。
content为FILE对象,如一切正常,使用FILE.chunks()依次将内容写入文件。
最后,根据file_permissions_mode参数,修改创建文件的权限。
def FileRecieveView(request):
"""接受用户上传的文件"""
if request.method == 'POST':
image = request.FILES['avatar']
if image.name.split('.')[-1] in ('jpg', 'jpeg', 'png', 'gif'):
save_path = settings.MEDIA_ROOT + '/users/avatars/' + image.name
# 服务器上保存图片的路径
file_path = default_storage.save(save_path, image)
# 文件的URL
file_url = 'http://127.0.0.1:8000' + settings.MEDIA_URL + 'users/avatars/' + file_path.split('/')[-1]
# 把对应的用户的头像修改掉
userprofile = request.user.profile
userprofile.avatar = file_url
userprofile.save()
# 把文件的URL链接返回给前端
message = file_url
status = 1
else:
message = '图像扩展名不正确,只接受:' + str(('jpg', 'jpeg', 'png', 'gif'))
status = -1
return JsonResponse({'status': status, 'message': message})
<div class="col-5 ">
<p>您当前的头像图片p>
<p><img id="img-avatar" src="{{ userprofile.avatar }}" width="200px"/>p>
<form id="form-avatar" method="post" enctype="multipart/form-data">
<div class="form-group">
<input type="file" class="form-control-file" name="avatar">
{% csrf_token %}
div>
form>
<button type="button" id="btn-upload-avatar" class="btn btn-primary">点击上传button>
div>
<script type="text/javascript">
$(document).ready(function () {
$("#btn-upload-avatar").on('click', function () {
alert("上传头像!");
// 用jquery获取的是jQuery对象,应该转为dom对象
let form = $("#form-avatar")[0];
let formData = new FormData(form);
$.ajax({
url: "{% url 'users:file_recieve' %}",
type: "POST",
data: formData,
cache: false, // 不缓存数据
processData: false, // 不处理数据
contentType: false, // 不设置内容类型
success: function (data) { //成功回调
console.log(data);
if(data.status===1){
alert(data.message);
}
else{
alert(data.message);
}
}
});
}
)
})
</script>