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 ; }

 

posted @ 2017-12-12 11:52  cls超  阅读(2241)  评论(0)    收藏  举报