django 图片上传(四种方式)、页面展示图片及相对路径配置外加图片预览功能
直接上代码,相信大家可以明白(全部流程以第一种上传方式为例:form表单上传)
上传THML代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/test3/" method="post" enctype="multipart/form-data"> <input type="file" name="oneimg"> <input type="submit" value="上传"> </form> </body> </html>
views视图函数的处理:
@csrf_exempt def test3(request): if request.method=='GET': return render(request, 'testimg.html') # print(request.POST.dict()) if request.method == 'POST': #上传 print('>>>>>', request.FILES) img_obj = request.FILES.get('oneimg') print('111',dir(img_obj)) print('222',img_obj.name) models.TestImg.objects.create(name=img_obj.name,imgs=img_obj) return HttpResponse('ok') def test_load_img(request): if request.method == 'GET': objs_list = [] all_img_objs = models.TestImg.objects.all() #获取所有的img对象 for one_img in all_img_objs: print(one_img.name) print(one_img.imgs.url) #这是imgs存储的绝对路径 return render(request,'test_load_img.html',{'all_img_objs':all_img_objs})
model文件写法:
class TestImg(models.Model): name = models.CharField(max_length=64,verbose_name='名称') #imgs = models.ImageField(verbose_name='图片', upload_to='img/%Y/%m') #指定一个文件夹用来存储上传的图片,该文件夹会自动创建 imgs = models.ImageField(upload_to = 'img') #本次使用的是这个 def __str__(self): return self.name class Meta: verbose_name_plural = '测试图片存储'
注意:这里的img是个对象实例,而你在真正要用到图片的实例的时候,应该这样写:testimg_obj.imgs.url、testimg_obj.imgs.name,因为model里,imgs字段是个文件对象,而不是个字符串,所以,对model里的imgs属性应当像对一个对象一样的拿取
存到数据库中是这样子的:
接下来看settings配置文件的设置:
STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR,'static') MEDIA_URL = '/home/wuchao/allfile/imgfile/' #这是配置ImageField中的upload_to指向的img/年/月 的文件夹,该文件夹在上传文件的时候会自动创建,在model字段中配置 MEDIA_ROOT = '/home/wuchao/allfile/' #这是通过nginx来管理静态文件时,在执行python manage.py collectstatic收集静态文件时,所有media文件收集后的存放位置 # MEDIA_ROOT = os.path.join(BASE_DIR,'media') STATICFILES_DIRS=( #通过相对路径从上之下自动检索文件的存储位置 os.path.join(BASE_DIR,"statics"), # obus.path.join(BASE_DIR,"/home/ta/uploadfile"), # os.path.join(BASE_DIR,"/home/wuchao/uploadfile"), os.path.join("/home/wuchao/uploadfile"), os.path.join("/home/wuchao/allfile/imgfile"), #图片都存在这个路径下的img文件夹中了,所以用相对路径/static/就能找到文件并获取文件内容 os.path.join("/home/wuchao/allfile/otherfile"), )
HTML配合相对路径展示图片代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {% for one_img in all_img_objs %} <img src="/static/{{ one_img.imgs }}" alt="tupian" style="height: auto;width: auto;">{{ one_img.imgs.name }} <!-- 需要使用/static/作为前缀是因为我们在settings配置文件中 STATICFILES_DIRS中--> {% endfor %} </body> </html>
上传文件的其他三种方式以及实例:
#urls.py url(r'^upload/$',views.upload), url(r'^upload_file/$',views.upload_file), #views.py def upload_file(request): username=request.POST.get("username") file_obj=request.FILES.get("fafafa") print(username,file_obj) with open(file_obj.name,'wb') as f: for item in file_obj.chunks():#一点一点上传 f.write(item) ret={"status":False,"data":request.POST.get("username")} return HttpResponse(json.dumps(ret)) #upload.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style> .upload{ display: inline-block;padding: 10px; background-color: brown; position: absolute; top: 0; bottom: 0; right: 0; left: 0; z-index: 90; } .file{ width: 100px;height: 50px;opacity: 0; position: absolute; top: 0; bottom: 0; right: 0; left: 0; z-index: 100; } </style> </head> <body> <div style="position: relative;width: 100px;height: 50px;"> <input class="file" type="file" id="fafafa" name="afafaf" /> <a class="upload">上传</a> </div> <input type="button" value="提交XHR" onclick="uploadXHR();"> <input type="button" value="提交jqury" onclick="uploadJquery();"> <form id="form1" action="/upload_file/" method="POST" enctype="multipart/form-data" target="ifm1"> <iframe id="ifm1" name="ifm1" style="display: none;"></iframe> <input type="file" name="fafafa" /> <input type="submit" onclick="iframeSubmit();" value="Form提交"/> </form> <script src="/static/jquery-1.12.4.js"></script> <script>
1、//jqury实现上传 function uploadJquery(){ //首先获取值 //$("#fafafa")[0]==document.getElementById("fafafa") //files表示你要上传的文件,上传的file可能有多个,但是我们这里只有一个所以是0, var file_obj=document.getElementById("fafafa").files[0] //这里file_obj是对象,send发送的是字符串,所以不能直接发送 var formdata=new FormData();//FormData表示是一个form表单 formdata.append("username","root");//key ,value formdata.append("fafafa",file_obj);//可以加对象,可以被send发送 $.ajax({ url: '/upload_file/', type: 'POST', data: formdata, processData: false, // tell jQuery not to process the data上传文件要设置 contentType: false, // tell jQuery not to set contentType上传文件要设置 success:function(arg,a1,a2){ console.log(arg); console.log(a1); console.log(a2); } }) } 2、//使用原生ajax实现上传 function uploadXHR(){ //首先获取值 //$("#fafafa")[0]==document.getElementById("fafafa") //files表示你要上传的文件,上传的file可能有多个,但是我们这里只有一个所以是0, var file_obj=document.getElementById("fafafa").files[0] //这里file_obj是对象,send发送的是字符串,所以不能直接发送 var formdata=new FormData();//FormData表示是一个form表单 formdata.append("username","root");//key ,value formdata.append("fafafa",file_obj);//可以加对象 //设置原生ajax对象 var xhr= new XMLHttpRequest() xhr.open("POST","/upload_file/",true); //回调函数,当状态变化时触发 xhr.onreadystatechange=function(){ //4是表示所有数据接受完了 if (xhr.readyState==4){ //获取返回值 console.log(xhr.responseText) //返回的是字符串 //转对象 JSON.parse(xhr.responseText) } } //上传文件不需要设置请求头 xhr.send(formdata);//发送的数据只能是字符串 } 3、//使用iframe实现上传 function iframeSubmit(){ $("#ifm1").load( function(){ //因为iframe里面有document,所以获取下面的元素先用contains. var content=$('#ifm1').contents().find('body').text(); console.log(content); } )} </script> </body> </html>
图片预览功能(原理就是找对文件的路径)
HTML部分:
<img id="pic" src="" > <input id="upload" name="file" accept="image/*" type="file" style="display: none"/>
input:file事件是上传类型
较常用的属性值如下:
accept:表示可以选择的文件MIME类型,多个MIME类型用英文逗号分开,常用的MIME类型见下表。
若要支持所有图片格式,则写 * 即可。
multiple:是否可以选择多个文件,多个文件时其value值为第一个文件的虚拟路径
input:file的样式是不变的,所以若要改变它的样式,首先将它隐藏。display:none;
css部分:
#pic{
width:100px;
height:100px;
border-radius:50% ; #这里做的是个圆形预览
margin:20px auto;
cursor: pointer;
}
jQuery部分:
$(function() {
$("#pic").click(function () {
$("#upload").click(); //隐藏了input:file样式后,点击头像就可以本地上传,这个功能自行填写
$("#upload").on("change",function(){
var objUrl = getObjectURL(this.files[0]) ; //获取图片的路径,该路径不是图片在本地的路径
if (objUrl) {
$("#pic").attr("src", objUrl) ; //将图片路径存入src中,显示出图片
}
});
});
});
//建立一個可存取到該file的url,这段是最主要的地方,原理是因为文件选择了以后,该文件已经加载到浏览器上了,并且浏览器给该文件创建了一个浏览器存储该文件的路径
//那么根据这个路径来预览图片,注意:这个路径不是我们选择图片时的本地路径,是window创建的。所以需要获取它,下面就是获取这个地址的方式。
function getObjectURL(file) {
var url = null ;
if (window.createObjectURL!=undefined) { // basic
url = window.createObjectURL(file) ;
} else if (window.URL!=undefined) { // mozilla(firefox)
url = window.URL.createObjectURL(file) ;
} else if (window.webkitURL!=undefined) { // webkit or chrome
url = window.webkitURL.createObjectURL(file) ;
}
return url ;
}