django中通过文件和Ajax来上传文件
一、通过form表单来上传文件
1.在html模板中
<form action="/index/" method="post" enctype="multipart/form-data">
#在form属性中写入enctype="multipart/form-data" 这样form表单才能支持数据文件的提交 {% csrf_token %} 头像<input type="file" name="touxiang" id="file"> <br> <label for="name">用户名</label> <input type="text" id="name" name="username"> <button id="btn">提交</button> </form>
2.在views视图中写入
def index(request): if request.method == 'GET': return render(request,'index.html') else: uname = request.POST.get('username') file = request.FILES.get('touxiang') #获取文件要通过.FILES.get()来获取文件数据 file_name = file.name path = os.path.join(settings.BASE_DIR,'statics','img',file_name)#来拼接文件内路径 with open(path,'wb')as f:#将文件写入本地 for i in file: f.write(i) return HttpResponse(uname)
当在后端接收文件内容的时候用FILES来接收,否者只能接收到文件名,
当用request.FILES.get('file')接收到之后,会接收到一个类似于文件句柄的数据类型,可以通过循环来读取文件,当文件是视频的时候,可以用句柄.chunks()来接收固定大小的文件,防止内存被占满
chunks()默认返回大小经测试位65536b,也就是64kb,最大是2.5MB,是一个生成器
二、Ajax来上传文件
1.在HTML模板中
$('#btn').click(function () { var formdata = new FormData();#ajax上传文件的时候,需要这个类型,它会将添加的键值对加工成formata的类型 formdata.append('uname',$('#name').val());#添加键值对的方法是append,注意写法,键和值之间使用逗号隔开 formdata.append('files',$('#file')[0].files[0]); formdata.append('csrfmiddlewaretoken',$('[name=csrfmiddlewaretoken]').val());#别忘了csrf_tocken $.ajax({ 'url':"{% url 'index' %}", 'type':'post', 'data':formdata,#将添加好的formdata放到data这里 processData:false, //不处理数据 contentType:false,//不设置内容类型 success:function (res) { console.log(res) } }) })
2.在视图函数中
def index(request): if request.method == 'GET': return render(request,'index.html') else: name = request.POST.get('uname')#获取POST请求发送过来的数据 file = request.FILES.get('tou')#获取上传文件的数据 file_name = file.name#获取文件名 path = os.path.join(settings.BASE_DIR,'statics','img',file_name)#拼接文件路径 with open(path,'wb')as f:#将文件写入本地 for i in file.chunks(): f.write(i)
三、JsonResponse
def index(request): if request.method == 'GET': return render(request,'index.html') else: # dd = {'k1':'v1','k2':'v2'} # dd = json.dumps(dd) # return HttpResponse(dd,content_type='application/json') #在发送的时候发送一个cntent_type='application/json'响应体,发送到模板中的ajax中会自动调用ajax的反序列化,就不需要手动反序列化了 #在python中同样也有,那就是JsonResponse对象 JsonResponse对象是HttpResponse的子类,专门用来生成JSON编码的响应 from django.http import JsonResponse #导入JsonResponse dd = {'k1':'v1','k2':'v2'} return JsonResponse(dd) #这样就不需要自己手动序列化了,也不需要自己手动写响应体了 dd = [11,22,33] return JsonResponse(dd,safe=False)#当序列化的是一个非字典的时候就需要safe=false,
四、json序列化时间日期类型的数据的方法
import json from datetime import datetime from datetime import date #对含有日期格式数据的json数据进行转换 class JsonCustomEncoder(json.JSONEncoder): def default(self, field): if isinstance(field,datetime): return field.strftime('%Y-%m-%d %H:%M:%S') elif isinstance(field,date): return field.strftime('%Y-%m-%d') else: return json.JSONEncoder.default(self,field) d1 = datetime.now() dd = json.dumps(d1,cls=JsonCustomEncoder) #当再调用json的时候就不能只写要序列化的数据了,在后面要写上cls=JsonCustomEncoder print(dd)