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

总结

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

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

总结

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

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

附加

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

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

总结

  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 上传图片文件的时候有预览功能

<!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里

原文地址:https://www.cnblogs.com/jiangchunsheng/p/8974732.html

时间: 2024-10-08 21:30:31

Django项目实战之用户头像上传与访问的相关文章

SSH系列:(10)用户管理-用户头像上传

用户头像上传是使用Struts的上传功能,因此需要遵循Struts上传文件的方式. 基本步骤: 1. 在JSP中使用 HTML 表单上传文件, 须把 HTML 表单的 enctype 属性设置为 multipart/form-data, method 属性设置为 post.HTML表单中包含<input type="file"> 使用户能选择上传文件. 2. Action 中添加三个文件上传相关的属性. 上传单个文件属性格式 属性一:类型为File,名字为页面file控件名

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" <form enctype="multipart/form-data" method="POST" action="{% url 'users:avatar_upload'%}">{% csrf_token %} <input type="file"

springboot 项目打包部署后设置上传文件访问的绝对路径

1.设置绝对路径 application.properties的配置 #静态资源对外暴露的访问路径 file.staticAccessPath=/upload/** #文件上传目录(注意Linux和Windows上的目录结构不同) #file.uploadFolder=/home/upload/ file.uploadFolder=d://upload/ 配置上传文件的目录,也可以在这里设置上传文件的大小 @Configuration public class UploadFileConfig

Canvas处理头像上传

未分类 最近社区系统需要支持移动端,其中涉及到用户头像上传,头像有大中小三种尺寸,在PC端,社区用Flash来处理头像编辑和生成,但该Flash控件的界面不友好而且移动端对Flash的支持不好,考虑到这些问题,最后我们选用Canvas来完成图像尺寸缩放和图片数据获取. 等边处理 头像一般都是正方形,首先我们需要获取图片宽度和高度的最小值,用该最小值作为边长居中裁剪图片,最终得到一个正方形的图片: var ImageEditor = function() { // 用离线canvas处理图片数据

django头像上传预览功能

页面格式 注册页面 这里可以看到有头像按钮, 头像需求 有默认的头像 点击头像就可以上传图片 上传图片后可以预览 生成默认的头像 上传默认图片到指定文件夹,然后把img标签的src指定到这里就可以, 点击头像上传图片 默认添加了<input type="file">后会在图片下面显示上传文件夹的选项,这个和我们当初想的不一样,我们可以通过把input标签和img标签重叠到一起,然后让input标签隐藏起来,这样出来的效果就是点击图片就可以点到input文件这个属性了 <

[Bootstrap-插件使用]Jcrop+fileinput组合实现头像上传功能

很久没有更新博客了,再不写点东西都烂了. 这次更新一个小内容,是两个插件的组合使用,实现头像上传功能. 业务需求: 头像上传功能,要对上传的文件进行剪切,且保证头像到服务器时必须是正方形的. 优化<input type="file">的显示样式,基础的样式实在太难看了. 上传的头像需要进行质量压缩跟大小裁剪,以减缓浏览器的压力. 成果预览: 使用到的技术插件 Jcrop:用于前端"裁剪"图片 bootstrap-fileinput:用于前端优化上传控件样

【Bootstrap-插件使用】Jcrop+fileinput组合实现头像上传功能

作者:Dreawer链接:https://zhuanlan.zhihu.com/p/24465742来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 作者:梦游的龙猫(转载已获得作者许可) 很久没有更新博客了,再不写点东西都烂了. 这次更新一个小内容,是两个插件的组合使用,实现头像上传功能. 业务需求: 头像上传功能,要对上传的文件进行剪切,且保证头像到服务器时必须是正方形的. 优化<input type="file">的显示样式,基础的样式实

移动端web头像上传实现截取和照片方向修复

实战所需js包: jQuery.Jcrop.EXIF 本次实战功能是在 app 中的 我的客户 的客户信息页面中实现移动端web的头像上传,本次没有实现图像拖拽.缩放的触摸事件功能(Jcrop在这方面的扩展支持实在不够良好,弄了半天没弄出来),若后续有更好的移动端web头像上传插件,可考虑后续替代升级. demo主要实现的关键功能: 图像的方向修正及图像截取 虽然没有实现图像拖拽和双指缩放,但其缩放后的相对于图像的比例计算和拖拽坐标计算规则是一致的,可以参考.同时图像的旋转功能也可参考其中的核心