django中文件上传是一种常常需要用到的最基本的技术之一,那么该怎么实现文件上传呢?这里介绍两种常用的文件上传的办法。
方案一:django内置的方法
'''
该方案需要用到django内置的字段 ImageField和FileField,同时需要用到pillow包,这里pillow是专门用来处理图像的库。
该两种字段使用时需要用到upload_to,即需要指定上传后的目录,photo=models.ImageField(upload_to='upload')
'''
# 示例
# models.py中
class Author(models.Model):
name = models.CharField(max_length=20)
photo = models.ImageField(upload_to='upload')
# views中
def upload(request):
name = request.POST.get("name")
photo = request.FILES.get('photo')
author = Author()
author.name = name
author.photo = photo #存储的时候,数据库存储的是路径
author.save()
# settings.py中
MEDIA_ROOT= os.path.join(BASE_DIR, 'static') # 文件存储在MEDIA_ROOT中
方案二:手动实现
'''
原生的io
这里需要用到一个函数 chunks():即将文件内容打碎,一块一块写入.
'''
# models中可以直接存储路径,即User.objects.get(id=id).update(photo='图片相对于服务器的路径')
# views.py的操作
def upload(req):
# 前端使用ajax上传文件
uploadFile = req.FILES.get('img')
print(uploadFile.__dict__)
fileName = str(uuid.uuid4())
if uploadFile.content_type == 'image/jpeg':
fileName += '.jpg'
saveFilePath = os.path.join(settings.MEDIA_ROOT, fileName)
with open(saveFilePath, 'wb') as f:
for part in uploadFile.chunks():
f.write(part)
f.flush() # 将内存数写入到文件中
return JsonResponse({'status': 'ok', 'name':fileName}, status=200)
return JsonResponse({'status': 'fail'}, status=200)
'''
这里前端的写法分为两种:
1)在存在csrf_token的时候我们需要
'''
<img id="tx" width="120px" height="120px" {% if user.photo %}src="{{ user.photo }}{% endif %}"><form>
{% csrf_token %}<input type="file" style="display: none" id="file" onchange="upload(this.files[0])">
</form>
<script>
function upload(file) {
var xhr = new XMLHttpRequest();
xhr.open('post', '/blogs/change_image', true);
xhr.onload = function () {
data = JSON.parse(xhr.responseText);
$('#tx').attr('src',data.data+'?tm='+Math.random());
};
// 封装post请求的表单数据
var formdata = new FormData();
formdata.append('img', file);
formdata.append('csrfmiddlewaretoken',
document.getElementsByName('csrfmiddlewaretoken')[0].value);
# 存在csrf_token时,需要将该值传入表单数据中
xhr.send(formdata);
}
</script>
# 2)如果不存在csrf_token的话
<input type="file" onchange="upload(this.files[0])"
id="file" style="display: none">
function upload(file) {
//上传文件
var xhr = new XMLHttpRequest();
xhr.open('post','/app/upload', true);
xhr.onload = function (ev) {
if(xhr.status == 200 && xhr.readyState==4){
console.log(xhr.responseText);
data = JSON.parse(xhr.responseText)
if(data.state == 'ok'){
$('#userImg').attr('src', '/static/'+data.path);
}
}
}
var formdata = new FormData();
formdata.append('img',file);
xhr.send(formdata);
}