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')

总结

这样,我们就做好了一个基本的文件上传小示例,这里需要注意的有几点:

  1. form表单里需要加上csrf_token验证
  2. 文件的input框的type的值为file
  3. 在视图函数中获取文件要用request.FILES.get()方法
  4. 通过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')

总结

上面已经实现了将文件上传到数据库的功能,需要注意的有几点:

  1. 所谓的上传到数据库,不是讲图片本身或者二进制码放在数据库,实际上也是将文件上传到服务器本地,数据库只是存了一个文件的路径,这样用户要调用文件的时候就可以通过路径去服务器指定的位置找了
  2. 创建ORM的时候,avatar字段要有一个upload_to=''的属性,指定上传后的文件放在哪里
  3. 往数据库添加的时候,文件字段属性赋值跟普通字段在形式上是一样的,如:models.User.objects.create(username=name,avatar=avatar)
  4. 如果有两个用户上传的文件名重复,系统会自动将文件改名,效果如下:

附加

功能我们是实现了,看起来我们在调用文件的时候,只需要通过数据库文件路径已经保存的文件本身就可以访问图片,让它出现在网页上,其实并不是这样,

我们需要配置一些东西,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')

总结

  1. Ajax上传的时候,按钮的tpye一定不要用submit
  2. Ajax上传的时候data参数的值不再是一个普通‘字典’类型的值,而是一个FormData对像
    • 创建对象formdata = new FormData();
    • 往里面添加值formdata.append('username',$('#name-input').val());
  3. Ajax在做post提交的时候要加上csrf验证
    • formdata.append("csrfmiddlewaretoken",$("[name='csrfmiddlewaretoken']").val());
  4. 最后,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参数,我们上传普通的字符串的时候不用指定,因为它有默认值,

而如果要传文件的话,就要另外指定了。总结以下几点

  1. form表单上传的话是通过 enctype="multipart/form-data" 来指定ContentType
  2. ajax上传的话是通过  processData:false 和 contentType:false来指定ContentType
  3. form上传的时候,文件数据是通过<input type="file">标签来‘’包裹‘’数据,
  4. ajax上传的时候,是通过一个 FormData 实例对象来添加数据,传递的时候传递这个对象就行了
  5. 数据传递过去之后,是封装在request.FILES里而不是request.POST里

Django用户头像上传的更多相关文章

  1. spring--mvc添加用户及用户头像上传

    spring--mvc添加用户及用户头像上传 添加用户步骤: 1.用ajax获取省份信息 2.添加用户 代码:register.jsp <meta http-equiv="Conten ...

  2. Django项目实战之用户头像上传与访问

      1 将文件保存到服务器本地 upload.html <!DOCTYPE html> <html lang="en"> <head> < ...

  3. Django项目实战—用户头像上传

    1 将文件保存到服务器本地 upload.html <!DOCTYPE html> <html lang="en"> <head> <me ...

  4. 使用jquery的imagecropper插件做用户头像上传 兼容移动端

    在移动端开发的过程中,或许会遇到对图片裁剪的问题.当然遇到问题问题,不管你想什么方法都是要进行解决的,哪怕是丑点,难看点,都得去解决掉. 图片裁剪的jquery插件有很多,我也测试过很多,不过大多数都 ...

  5. Vue+axios+Node+express实现文件上传(用户头像上传)

    Vue 页面的代码 <label for='my_file' class="theme-color"> <mu-icon left value="bac ...

  6. python全栈开发day75-用户注册页面ajax实现,用户头像上传、预览、展示

    一.昨日内容回顾 1. 内容回顾 1. BBS项目登录 1. 登录用form组件和auth模块 1. form组件做校验很方便 2. auth模块 - authenticate(username=xx ...

  7. 微信小程序--更换用户头像/上传用户头像/更新用户头像

    changeAvatar:function (){ var that=this; wx.chooseImage({ count: 1, // 默认9 sizeType: ['original', 'c ...

  8. Canvas处理头像上传

    未分类 最近社区系统需要支持移动端,其中涉及到用户头像上传,头像有大中小三种尺寸,在PC端,社区用Flash来处理头像编辑和生成,但该Flash控件的界面不友好而且移动端对Flash的支持不好,考虑到 ...

  9. Django实现注册页面_头像上传

    Django实现注册页面_头像上传 Django实现注册页面_头像上传 1.urls.py 配置路由 from django.conf.urls import url from django.cont ...

随机推荐

  1. 2-19-使用apache搭建web网站

    1 搭建一台测试web服务器 案例: 部门内部搭建一台WEB服务器,采用的IP地址和端口为192.168.10.34:80,首页采用index.html 文件.管理员E-mail地址为 xuegod@ ...

  2. 通通玩blend美工(1)——荧光Button

    原文:通通玩blend美工(1)--荧光Button 最近老大出差去了,光做项目也有点烦,写点教程消遣消遣(注:此乃初级教程,所以第一个消遣是本人消遣,第二个是指供各位看官消遣...) 看着各位大虾出 ...

  3. win10 uwp 异步转同步

    原文:win10 uwp 异步转同步 有很多方法都是异步,那么如何从异步转到同步? 可以使用的方法需要获得是否有返回值,返回值是否需要. 如果需要返回值,使用GetResults 如从文件夹获取文件: ...

  4. Win10的UWP之标题栏的返回键(二)

    原文:Win10的UWP之标题栏的返回键(二) 关于Win10的UWP的返回键的第二种处理的方法,是介于标题栏的强行修改,不是像上期的那样直接调用系统内置的API. - - - - - - - - - ...

  5. .NET DataTable转换为JSON格式的字符串

    在进行数据传递的时候,有时我们需要通过Ajax的方式或者其他的方式传递一个数据列表,可以将DataTable或者其他形式的数据列表转换为JSON的格式,通过Ajax实体的形式进行传递. 比如说: // ...

  6. Android卡片设置透明度失效问题

    最近在做蓝牙电话项目,需要支持双路通话,涉及到通话卡片透明度调节,当正在通话中,有新的来电时,原来的通话卡片需要做成30%的透明度,本来很简单的一个小改进,但通过 setAlpha()接口总是失效!  ...

  7. DirectX的替代品 SDL 简介

    DirectX的替代品 SDL 简介 什么是SDL? 即 Simple DirectMedia Layer,使用 LGPL 许可证. 免费的跨平台多媒体应用编程接口 用于游戏.游戏开发工具.模拟器.样 ...

  8. Qt之OpenSSL(有pro文件的路径格式,以及对libeay32和ssleay32的引用)

    简述 OpenSSL是一个强大的安全套接字层密码库,囊括主要的密码算法.常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用. 简述 下载安装 使用 更多参考 下载安装 ...

  9. 海康威视频监控设备Web查看系统(三):Web篇

    声明:本系列文章只提供交流与学习使用.文章中所有涉及到海康威视设备的SDK均可在海康威视官方网站下载得到.文章中所有除官方SDK以为的代码均可随意使用,任何涉及到海康威视公司利益的非正常使用由使用者自 ...

  10. Mariadb的安装与使用

    一.安装Mariadb 参考博客:https://www.cnblogs.com/pyyu/p/9467289.html 安装软件的三中方式 yum原码编译安装下载rpm安装 yum与原码编译安装安装 ...