Django项目实战之用户头像上传与访问
1 将文件保存到服务器本地
upload.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"> </head>
<body> <form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<div>用户名:<input type="text" name="username"></div>
<div>头像<input type="file" name="avatar"></div>
<input type="submit" value="提交">
</form> </body>
</html>
urls.py
from django.conf.urls import url
from app01 import views urlpatterns = [
url(r'^upload',views.upload)
]
views.py
from django.shortcuts import render,HttpResponse def upload(request):
if request.method == 'POST':
name = request.POST.get('username')
avatar = request.FILES.get('avatar') with open(avatar.name,'wb') as f:
for line in avatar:
f.write(line)
return HttpResponse('ok') return render(request,'upload.html')
总结
这样,我们就做好了一个基本的文件上传小示例,这里需要注意的有几点:
- form表单里需要加上csrf_token验证
- 文件的input框的type的值为file
- 在视图函数中获取文件要用request.FILES.get()方法
- 通过obj.name可以获取文件的名字
2 将文件上传到数据库
models.py
from django.db import models class User(models.Model):
username = models.CharField(max_length=16)
avatar = models.FileField(upload_to='avatar')
views.py
def upload(request):
if request.method == 'POST':
name = request.POST.get('username')
avatar = request.FILES.get('avatar') models.User.objects.create(username=name,avatar=avatar)
return HttpResponse('ok') return render(request,'upload.html')
总结
上面已经实现了将文件上传到数据库的功能,需要注意的有几点:
- 所谓的上传到数据库,不是讲图片本身或者二进制码放在数据库,实际上也是将文件上传到服务器本地,数据库只是存了一个文件的路径,这样用户要调用文件的时候就可以通过路径去服务器指定的位置找了
- 创建ORM的时候,avatar字段要有一个upload_to=''的属性,指定上传后的文件放在哪里
- 往数据库添加的时候,文件字段属性赋值跟普通字段在形式上是一样的,如:models.User.objects.create(username=name,avatar=avatar)
- 如果有两个用户上传的文件名重复,系统会自动将文件改名,效果如下:
附加
功能我们是实现了,看起来我们在调用文件的时候,只需要通过数据库文件路径已经保存的文件本身就可以访问图片,让它出现在网页上,其实并不是这样,
我们需要配置一些东西,django才可以找的到,不然的话就会过不了urls验证,而我们之所以可以直接访问static里的静态文件,是因为django已经帮我们配置好了。
配置步骤如下:
1、在站点的setting.py里配置
MEDIA_ROOT=os.path.join(BASE_DIR,"blog","media") #blog是项目名,media是约定成俗的文件夹名
MEDIA_URL="/media/" # 跟STATIC_URL类似,指定用户可以通过这个路径找到文件
2、在urls.py里配置
from django.views.static import serve
from upload import settings #upload是站点名 url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
配置完后,就可以通过http://127.0.0.1:8001/media/milk.png访问到图片了
3 用AJAX提交文件
upload.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body> <form>
{% csrf_token %}
<div>用户名:<input id="name-input" type="text"></div>
<div>头像<input id="avatar-input" type="file"></div>
<input id="submit-btn" type="button" value="提交">
</form> <script src="/static/js/jquery-3.2.1.min.js"></script>
<script>
$('#submit-btn').on('click',function () {
formdata = new FormData();
formdata.append('username',$('#name-input').val()); formdata.append("avatar",$("#avatar")[0].files[0]);
formdata.append("csrfmiddlewaretoken",$("[name='csrfmiddlewaretoken']").val());
$.ajax({
processData:false,
contentType:false,
url:'/upload',
type:'post',
data:formdata,
success:function (arg) {
if (arg.state == 1){ alert('成功!') }else { alert('失败!') } } }) });
</script> </body> </html>
views.py
from django.shortcuts import render,HttpResponse
from django.http import JsonResponse
from app01 import models def upload(request):
if request.method == 'POST':
name = request.POST.get('username')
avatar = request.FILES.get('avatar') try:
models.User.objects.create(username=name,avatar=avatar)
data = {'state':1}
except:
data = {'state':0} return JsonResponse(data) return render(request,'upload.html')
总结
- Ajax上传的时候,按钮的tpye一定不要用submit
- Ajax上传的时候data参数的值不再是一个普通‘字典’类型的值,而是一个FormData对像
- 创建对象formdata = new FormData();
- 往里面添加值formdata.append('username',$('#name-input').val());
- Ajax在做post提交的时候要加上csrf验证
- formdata.append("csrfmiddlewaretoken",$("[name='csrfmiddlewaretoken']").val());
- 最后,Ajax上传文件的时候要有两个参数设置
- processData:false
- contentType:false
4 上传图片文件的时候有预览功能
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body> <form>
<!----用一个label标签将上传文件输入框跟图片绑定一起,
点击图片的时候就相当于点击了上传文件的按钮---->
<label><img id="avatar-img" src="/static/img/default.png" width="80px" height="80px">
<div>头像<input id="avatar-input" hidden type="file"></div>
</label> <input id="submit-btn" type="button" value="提交">
</form> <script src="/static/js/jquery-3.2.1.min.js"></script> <script> // 上传文件按钮(label里的图片)点击事件
$('#avatar-input').on('change',function () {
// 获取用户最后一次选择的图片
var choose_file=$(this)[0].files[0];
// 创建一个新的FileReader对象,用来读取文件信息
var reader=new FileReader();
// 读取用户上传的图片的路径
reader.readAsDataURL(choose_file);
// 读取完毕之后,将图片的src属性修改成用户上传的图片的本地路径
reader.onload=function () {
$("#avatar-img").attr("src",reader.result)
}
}); </script>
5 大总结
对于文件上传,不管是直接form提交也好,Ajax提交也好,根本问题是要告诉浏览器你要上传的是一个文件而不是普通的字符串
而怎么样告诉浏览器呢,就是通过请求体重的ContentType参数,我们上传普通的字符串的时候不用指定,因为它有默认值,
而如果要传文件的话,就要另外指定了。总结以下几点
- form表单上传的话是通过 enctype="multipart/form-data" 来指定ContentType
- ajax上传的话是通过 processData:false 和 contentType:false来指定ContentType
- form上传的时候,文件数据是通过<input type="file">标签来‘’包裹‘’数据,
- ajax上传的时候,是通过一个 FormData 实例对象来添加数据,传递的时候传递这个对象就行了
- 数据传递过去之后,是封装在request.FILES里,而不是request.POST里
Django项目实战之用户头像上传与访问的更多相关文章
- Django实现注册页面_头像上传
Django实现注册页面_头像上传 Django实现注册页面_头像上传 1.urls.py 配置路由 from django.conf.urls import url from django.cont ...
- spring--mvc添加用户及用户头像上传
spring--mvc添加用户及用户头像上传 添加用户步骤: 1.用ajax获取省份信息 2.添加用户 代码:register.jsp <meta http-equiv="Conten ...
- Django项目实战—用户头像上传
1 将文件保存到服务器本地 upload.html <!DOCTYPE html> <html lang="en"> <head> <me ...
- Django项目实战之用户上传与访问
1 将文件保存到服务器本地 upload.html <!DOCTYPE html> <html lang="en"> <head> <me ...
- Django用户头像上传
1 将文件保存到服务器本地 upload.html ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <!DOCTYPE html> <html ...
- 使用jquery的imagecropper插件做用户头像上传 兼容移动端
在移动端开发的过程中,或许会遇到对图片裁剪的问题.当然遇到问题问题,不管你想什么方法都是要进行解决的,哪怕是丑点,难看点,都得去解决掉. 图片裁剪的jquery插件有很多,我也测试过很多,不过大多数都 ...
- Vue+axios+Node+express实现文件上传(用户头像上传)
Vue 页面的代码 <label for='my_file' class="theme-color"> <mu-icon left value="bac ...
- springboot 项目打包部署后设置上传文件访问的绝对路径
1.设置绝对路径 application.properties的配置 #静态资源对外暴露的访问路径 file.staticAccessPath=/upload/** #文件上传目录(注意Linux和W ...
- python全栈开发day75-用户注册页面ajax实现,用户头像上传、预览、展示
一.昨日内容回顾 1. 内容回顾 1. BBS项目登录 1. 登录用form组件和auth模块 1. form组件做校验很方便 2. auth模块 - authenticate(username=xx ...
随机推荐
- Java程序员的情书
java程序员的情书 我能抽象出整个世界但是我不能抽象出你因为你在我心中是那么的具体所以我的世界并不完整我可以重载甚至覆盖这个世界里的任何一种方法但是我却不能重载对你的思念也许命中注定了 你在我的世界 ...
- 在删除一个指针之后,一定将该指针设置成空指针(即在delete *p之后一定要加上: p=NULL)
在删除一个指针之后,一定将该指针设置成空指针(即在delete *p之后一定要加上: p=NULL)
- find()用法
>>> str = '编程改变世界'>>> str.find('编')0>>> str.find('程')1>>> str.fi ...
- PHP简单判断手机设备的方法
本文实例讲述了PHP简单判断手机设备的方法.分享给大家供大家参考,具体如下: 现在移动互联网越来越发到,很多的网站都普及了手机端浏览,为了更好的让网页在手机端显示,我们都选择了使用CSS媒体查询制作响 ...
- VINS 估计器之检查视差
为什么检查视差 VINS里为了控制优化计算量,在实时情况下,只对当前帧之前某一部分帧进行优化,而不是全部历史帧.局部优化帧的数量就是窗口大小.为了维持窗口大小,需要去除旧的帧添加新的帧,也就是边缘化 ...
- selenium chrome浏览器与chrome.driver的对应关系
看到网上基本没有最新的chromedriver与chrome的对应关系表,便兴起整理了一份如下,希望对大家有用: chromedriver版本 支持的Chrome版本 v2.34 v61-63 v2. ...
- python 云打码 hhtp接口
import http.client, mimetypes, urllib, json, time, requests ######################################## ...
- 微信的自动回复&接入聊天机器人
今天偶尔发现了一个有趣的python库--itchat,可以实现微信的自动回复.防撤回,结合图灵机器人还能实现聊天机器人的作用 简单介绍一下配置与工具 win7旗舰版 pycharm python ...
- seacms6.5 注入漏洞1
---恢复内容开始--- 需要开启/data/admin/isapi.txt ,当里面的数值为1时,就可以报错注入 存在漏洞的页面:zyapi.php function cj() { global ...
- [USACO 12DEC]Running Away From the Barn
Description It's milking time at Farmer John's farm, but the cows have all run away! Farmer John nee ...