django的文件上传

django中文件上传是一种常常需要用到的最基本的技术之一,那么该怎么实现文件上传呢?这里介绍两种常用的文件上传的办法。

方案一:django内置的方法

'''
 该方案需要用到django内置的字段  ImageField和FileField,同时需要用到pillow包,这里pillow是专门用来处理图像的库。
该两种字段使用时需要用到upload_to,即需要指定上传后的目录,photo=models.ImageField(upload_to='upload')

'''
# 示例
# models.py中
class Author(models.Model):
    name = models.CharField(max_length=20)
    photo = models.ImageField(upload_to='upload')


# views中
def upload(request):
    name = request.POST.get("name")
    photo = request.FILES.get('photo')
    author = Author()
    author.name = name
    author.photo = photo   #存储的时候,数据库存储的是路径
    author.save()

# settings.py中
MEDIA_ROOT= os.path.join(BASE_DIR, 'static')   # 文件存储在MEDIA_ROOT中

方案二:手动实现

'''
原生的io
这里需要用到一个函数  chunks():即将文件内容打碎,一块一块写入.

'''

# models中可以直接存储路径,即User.objects.get(id=id).update(photo='图片相对于服务器的路径')

# views.py的操作

def upload(req):
    # 前端使用ajax上传文件
    uploadFile = req.FILES.get('img')
    print(uploadFile.__dict__)
    fileName = str(uuid.uuid4())
    if uploadFile.content_type == 'image/jpeg':
        fileName += '.jpg'

    saveFilePath = os.path.join(settings.MEDIA_ROOT, fileName)

    with open(saveFilePath, 'wb') as f:
        for part in uploadFile.chunks():
            f.write(part)
            f.flush()   # 将内存数写入到文件中
        return JsonResponse({'status': 'ok', 'name':fileName}, status=200)

    return JsonResponse({'status': 'fail'}, status=200)


'''
这里前端的写法分为两种:
1)在存在csrf_token的时候我们需要

'''
<img id="tx" width="120px" height="120px" {% if user.photo %}src="{{ user.photo }}{% endif %}"><form>
    {% csrf_token %}<input type="file" style="display: none" id="file" onchange="upload(this.files[0])">
    </form>

<script>
    function upload(file) {
        var xhr = new XMLHttpRequest();
        xhr.open('post', '/blogs/change_image', true);
        xhr.onload = function () {
            data = JSON.parse(xhr.responseText);
            $('#tx').attr('src',data.data+'?tm='+Math.random());

        };
        // 封装post请求的表单数据
        var formdata = new FormData();
        formdata.append('img', file);
        formdata.append('csrfmiddlewaretoken',  
            document.getElementsByName('csrfmiddlewaretoken')[0].value);
            # 存在csrf_token时,需要将该值传入表单数据中
        xhr.send(formdata);

    }


</script>



  # 2)如果不存在csrf_token的话

 <input type="file" onchange="upload(this.files[0])"
           id="file" style="display: none">


function upload(file) {
    //上传文件
    var xhr = new XMLHttpRequest();
    xhr.open('post','/app/upload', true);
    xhr.onload = function (ev) {
        if(xhr.status == 200 && xhr.readyState==4){
            console.log(xhr.responseText);
            data = JSON.parse(xhr.responseText)
            if(data.state == 'ok'){
                $('#userImg').attr('src', '/static/'+data.path);
            }
        }
    }

    var formdata = new FormData();
    formdata.append('img',file);
    xhr.send(formdata);
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值