Django用户头像上传
1 将文件保存到服务器本地
upload.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<!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
1
2
3
4
5
6
|
from django.conf.urls import url from app01 import views urlpatterns = [ url(r '^upload' ,views.upload) ] |
views.py
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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
1
2
3
4
5
6
|
from django.db import models class User(models.Model): username = models.CharField(max_length = 16 ) avatar = models.FileField(upload_to = 'avatar' ) |
views.py
1
2
3
4
5
6
7
8
9
|
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里配置
1
2
|
MEDIA_ROOT = os.path.join(BASE_DIR, "blog" , "media" ) #blog是项目名,media是约定成俗的文件夹名 MEDIA_URL = "/media/" # 跟STATIC_URL类似,指定用户可以通过这个路径找到文件 |
2、在urls.py里配置
1
2
3
4
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<!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());<br><br> formdata.append( "avatar" ,$( "#avatar" )[ 0 ].files[ 0 ]); |
1
|
formdata.append( "csrfmiddlewaretoken" ,$( "[name='csrfmiddlewaretoken']" ).val()); <br> $.ajax({<br> processData:false,<br> contentType:false, <br> url: '/upload' , <br> type : 'post' , <br> data:formdata, <br> success:function (arg) { <br> if (arg.state = = 1 ){ alert( '成功!' ) } else { alert( '失败!' ) } } }) });<br> < / script> < / body> < / html> |
views.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
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 上传图片文件的时候有预览功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
<!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用户头像上传的更多相关文章
- spring--mvc添加用户及用户头像上传
spring--mvc添加用户及用户头像上传 添加用户步骤: 1.用ajax获取省份信息 2.添加用户 代码:register.jsp <meta http-equiv="Conten ...
- Django项目实战之用户头像上传与访问
1 将文件保存到服务器本地 upload.html <!DOCTYPE html> <html lang="en"> <head> < ...
- Django项目实战—用户头像上传
1 将文件保存到服务器本地 upload.html <!DOCTYPE html> <html lang="en"> <head> <me ...
- 使用jquery的imagecropper插件做用户头像上传 兼容移动端
在移动端开发的过程中,或许会遇到对图片裁剪的问题.当然遇到问题问题,不管你想什么方法都是要进行解决的,哪怕是丑点,难看点,都得去解决掉. 图片裁剪的jquery插件有很多,我也测试过很多,不过大多数都 ...
- Vue+axios+Node+express实现文件上传(用户头像上传)
Vue 页面的代码 <label for='my_file' class="theme-color"> <mu-icon left value="bac ...
- python全栈开发day75-用户注册页面ajax实现,用户头像上传、预览、展示
一.昨日内容回顾 1. 内容回顾 1. BBS项目登录 1. 登录用form组件和auth模块 1. form组件做校验很方便 2. auth模块 - authenticate(username=xx ...
- 微信小程序--更换用户头像/上传用户头像/更新用户头像
changeAvatar:function (){ var that=this; wx.chooseImage({ count: 1, // 默认9 sizeType: ['original', 'c ...
- Canvas处理头像上传
未分类 最近社区系统需要支持移动端,其中涉及到用户头像上传,头像有大中小三种尺寸,在PC端,社区用Flash来处理头像编辑和生成,但该Flash控件的界面不友好而且移动端对Flash的支持不好,考虑到 ...
- Django实现注册页面_头像上传
Django实现注册页面_头像上传 Django实现注册页面_头像上传 1.urls.py 配置路由 from django.conf.urls import url from django.cont ...
随机推荐
- dumpbin判断windows程序是32还是64位(包括DLL)
http://blog.csdn.net/csfreebird/article/details/10105681 dumpbin /HEADERS gdal18.dll(or xxx.exe) 如果安 ...
- js 层的显示和隐藏
<!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/xhtml"> ...
- c# 自定义公共类CallFunction-调用函数信息帮助类
/// <summary> /// 调用函数信息 /// </summary> public class CallFunction { /// <summary> ...
- 百度蜘蛛ip段代表的不同含义
有时候我们在分析百度蜘蛛的时候,会发现很多的ip,这些个ip地址,根据后面的参数可以发现都是百度的.刚学习SEO不久的同学肯定要问:这些ip地址到底代表什么含义,是不是不同的ip地址所代表的含义不一样 ...
- 没必要看源码。。把文档学通就已经牛逼了(我们大多还是在应用层,还达不到研究的程度。附class与examples大全链接)
[学霸]深圳-鑫 2017/7/11 13:54:07只是学习怎么用QT的话,不用看源码.看帮助文档就很好要学习编码风格与思路,就看看源码 [学神]武汉-朝菌 2017/7/11 13:54:39没必 ...
- C、C++笔记
2017年6月 阅读书籍<C和指针> #if 0 #endif 比注释掉代码好.(<C和指针>2017.06.07) 全局变量和全局静态变量的区别 1)全局变量是不显式用sta ...
- 社会不是承认有学历的人, 而是承认努力过得人, 而且是真正努力过不是穷忙的人(没有学历就要多付出一倍的努力)good
送你一句 这就是你水平差的理由? 楼主你工资低是因为你技术不行, 不想努力然后怪罪学历, 为什么学历高的混得好, 因为学历高的人努力过, 你没学历技术还不行, 凭什么证明你努力过, 社会不是承认有学历 ...
- Mono 4.0 发布,开源跨平台 .Net 框架
快速使用Romanysoft LAB的技术实现 HTML 开发Mac OS App,并销售到苹果应用商店中. <HTML开发Mac OS App 视频教程> 土豆网同步更新:http: ...
- windows qt 使用c++ posix接口编写多线程程序(真神奇)good
一.多线程是多任务处理的一种特殊形式,多任务处理允许让电脑同时运行两个或两个以上的程序.一般情况下,两种类型的多任务处理:基于进程和基于线程.基于进程的多任务处理是程序的并发执行.基于线程的多任务处理 ...
- Model-View-Controller Explained in C++
The Permanent URL is: Model-View-Controller Explained in C++. The Model-View-Controller (MVC) is not ...