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里

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

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

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

  2. 【django】本地开发media用户上传文件访问路径找不到

    当我们在本地开发的时候,会碰到static可以访问,但是用户上传的文件设置在media下不可访问怎么办?settings配置: 接着在你的urls文件添加: from . import setting ...

  3. 最近开发的项目,遇到用户上传excel文件并导入数据到系统这个需求,而有excel中有的单元格是日期格式,本文介绍怎么从excel中读取日期格式的数据。

    可以先判断单元格的类型,有的日期是字符串存储的,有的是按日期存储的(单元格按数字解析),代码如下: Cell cell = row.getCell(); Date date = null; if (c ...

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

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

  5. Django之用户上传文件的参数配置

    Django之用户上传文件的参数配置 models.py文件 class Xxoo(models.Model): title = models.CharField(max_length=128) # ...

  6. django 用户上传文件media的存储访问配置1

    1. 首先新建文件夹media  后 在项目setting中具体配置: MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media ...

  7. 利用django如何解析用户上传的excel文件

    https://www.jb51.net/article/119452.htm 前言 我们在工作中的时候,会有这种需求:用户上传一个格式固定excel表格到网站上,然后程序负债解析内容并进行处理.我最 ...

  8. 7月3日 Django 头像预览、用户上传文件操作、logging、debug_tool_bar

    1. 注册功能 1. 头像预览 //头像预览 $('#id_avatar').change(function () { console.log(this.files[0]) //找到选中的头像文件 v ...

  9. 用eclipse怎样将本地的项目打成jar包上传到maven仓库

    使用maven的项目中,有时需要把本地的项目打成jar包上传到mevan仓库. 操作如下: 前提:pom文件中配置好远程库的地址,否则会报错 1.将maven 中的settings文件配置好用户名和密 ...

随机推荐

  1. javascript中词法环境、领域、执行上下文以及作业详解

    词法环境(Lexical Environments) 官方规范对词法环境的说明是:词法环境(Lexical Environments)是一种规范类型,用于根据ECMAScript代码的词法嵌套结构来定 ...

  2. 在JavaScript里 (a ==1 && a== 2 && a==3) 有可能是 true 吗?

    ps:今天看到这个有趣的问题,跟大家分享下 一个有趣的问题: 在 JavaScript 中, (a ==1 && a== 2 && a==3) 是否有可能为 true ...

  3. SSE(Server-sent events)技术在web端消息推送和实时聊天中的使用

    最近在公司闲着没事研究了几天,终于搞定了SSE从理论到实际应用,中间还是有一些坑的. 1.SSE简介 SSE(Server-sent events)翻译过来为:服务器发送事件.是基于http协议,和W ...

  4. Oracle查询优化改写--------------------范围处理

    一.定位连续值的范围 二.查找同一组或分区中行之间的差

  5. jQuery学习笔记 .addClass()/.removeClass()简单学习

    使用jQuery或javaScript来动态改变页面中某个或部分元素的样式,为了实现这样的功能,我们往往都是使用jQuery或javaScript来控制HTML中DOM的类名(class)从而实现增加 ...

  6. C++中输出流的刷新问题和 endl和 \n的区别

    <C++ Primer>第5版 P6中提到endl具有换行和刷新输出流两个作用,那么没有 endl是否还会将输出流中的内容输出到设备中,再刷新输出流呢? cout << &qu ...

  7. python全栈学习--day5

    字典 特点:字典是python中唯一的映射类型,采用键值对(key-value) 的形式存数据. 存储大量的数据,是关系型数据,查询数据快. 字典初始说明: 遍历字典从列表开始,列表是从头便利到尾的. ...

  8. Java基础学习笔记总结

    Java基础学习笔记一 Java介绍 Java基础学习笔记二 Java基础语法之变量.数据类型 Java基础学习笔记三 Java基础语法之流程控制语句.循环 Java基础学习笔记四 Java基础语法之 ...

  9. SpringMVC学习笔记三 整合jdbc和事务

    spring整合JDBC spring提供了很多模板整合Dao技术,用于简化编程. 引入相关jar包 spring中提供了一个可以操作数据库的对象,JDBCTemplate(JDBC模板对象).对象封 ...

  10. C#触发器知识总结及案例

    触发器 触发器是在对表进行插入.更新.删除操作时自动执行的存储过程,常用于强制业务规则,是一种高级约束,可以定义比用check约束更为复杂的约束.可以执行复杂的SQL语句(if/while/case) ...