目录
一、文件上传
二、Models补充
三、Django总结
一、文件上传
1、通过form表单或者通过From类上传
- views.py
from django.shortcuts import render,HttpResponse from django import forms from django.forms import fields class UploadForm(forms.Form): user = fields.CharField() img = fields.FileField() def upload(request): '''上传文件''' if request.method == 'GET': return render(request,'upload.html') else: ''' # 基于Form也可以上传,这里还做了验证 obj = UploadForm(request.POST,request.FILES) if obj.is_valid(): user = obj.cleaned_data['user'] img = obj.cleaned_data['img'] ''' #img是对象,封装了文件大小、名称、内容。。。 img = request.FILES.get('img') print(img.name) print(img.size) #将上传文件写入本地 f = open(img.name,'wb') #上传是一点一点的,所以不能一下子拿到全部,需要循环 for line in img.chunks(): f.write(line) f.close() return HttpResponse('上传成功')
- upload.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> #c1{ position: absolute; top:0; left:0; opacity: 0; } #c2{ background-color: dodgerblue; border: 1px solid lightblue; font-size: 20px; } </style> </head> <body> <form action="/upload.html" method="POST" enctype="multipart/form-data"> <input type="text" name="user"/> {#修改上传按钮的样式,其实就是把按钮隐藏,上面覆盖一个新的按钮#} <div style="position: relative;"> <a id="c2">新上传</a> <input type="file" name="img" id="c1"/> </div> <input type="submit" value="提交"/> </form> </body> </html>
2、jQuery ajax和原生的ajax上传
-
两者都用到了同一个类FormData()来封装用户提交的数据,本质上ajax和原生ajax原理一样,因为底层都是用的类XMLHttpRequest;
-
但是不是每一个浏览器都有FormData(),有一些低版本的IE可能不支持;所以如果考虑兼容性的问题,尽量用iframe + form的形式;
-
views.py
#将文件保存到本地,对下面两个方式都适用 def ajax1(request): ret = {'status':True,'msg':'666'} import json data = request.FILES.get('k') f = open(data.name,'wb') for line in data: f.write(line) f.close() return HttpResponse(json.dumps(ret))
- index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> {% load staticfiles %} <style> .btn{ display: inline-block; padding: 5px 10px; background-color: #2aabd2; color: white; cursor: pointer; } </style> </head> <body> <h3>Ajax上传文件</h3> <input type="file" id="img"/> <a class="btn" onclick="ajaxSubmit6();">ajax上传</a> <a class="btn" onclick="ajaxSubmit7();">原生ajax上传</a> <script src="{% static 'js/jquery-1.12.4.js' %}"></script> <script> //上传文件 //通过FormData function ajaxSubmit6() { //得到img标签上传的文件 var f = document.getElementById('img').files[0]; var data = new FormData(); data.append('k',f); $.ajax({ url:'/ajax1.html', type:'POST', data:data, processData: false, // tell jQuery not to process the data contentType: false, // tell jQuery not to set contentType success:function (arg) { console.log(arg); } }) } //通过原生ajax上传 function ajaxSubmit7() { var f = document.getElementById('img').files[0]; var data = new FormData(); data.append('k',f); var xhr = new XMLHttpRequest(); xhr.open('POST','/ajax1.html'); xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ console.log(xhr.responseText); } }; xhr.send(data); } </script> </body> </html>
3、iframe + form 上传文件
-
iframe默认是不显示的;
-
views.py
def ajax1(request): ret = {'status':True,'msg':'666'} import json #iframe + form 上传文件 data = request.FILES.get('img3') f = open(data.name,'wb') for line in data: f.write(line) f.close() return HttpResponse(json.dumps(ret))
- index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> {% load staticfiles %} <style> .btn{ display: inline-block; padding: 5px 10px; background-color: #2aabd2; color: white; cursor: pointer; } </style> </head> <body> <h2>5.基于iframe+Form上传文件</h2> <div> <iframe id="iframe3" name="frame3" style="display: none;" ></iframe> <form id="fm3" action="/ajax1.html" method="POST" target="frame3" enctype="multipart/form-data"> <input type="file" name="img3"/> <a onclick="ajaxSubmit8();" class="btn">iframe上传</a> </form> </div> <script src="{% static 'js/jquery-1.12.4.js' %}"></script> <script> //iframe+form上传 function ajaxSubmit8() { document.getElementById('iframe3').onload = reloadIframe3; document.getElementById('fm3').submit(); } //相当于回调函数,通过判断后台返回的消息来进行下一步操作,只不过后台返回的内容在iframe中 function reloadIframe3() { var content = this.contentWindow.document.body.innerText; var ret = JSON.parse(content); if(ret.status){ alert('000'); } } </script> </body> </html>
4、上传图片时在页面上预览
- views.py
from django.shortcuts import render,HttpResponse import json import os import uuid def upload(request): return render(request,'upload.html') def upload_img(request): ret = {'status': True,'data':None, 'msg': None} obj = request.FILES.get('img') #为避免文件名重复被覆盖,文件名加个前缀 nid = str(uuid.uuid4()) file_path = os.path.join('static',nid+obj.name) f = open(file_path, 'wb') for line in obj.chunks(): f.write(line) f.close() ret['data'] = file_path return HttpResponse(json.dumps(ret))
- upload.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> {% load staticfiles %} <style> .btn{ background-color: #2aabd2; color: white; cursor: pointer; padding: 4px 2px; } .upload{ position: absolute; top:0; left:0; opacity: 0; } </style> </head> <body> <h2>基于iframe+Form上传文件</h2> <div> <iframe id="iframe" name="fram" style="display: none;" ></iframe> <form id="fm" action="/upload_img.html" method="POST" target="fram" enctype="multipart/form-data"> <div style="position: relative"> <a class="btn">iframe上传</a> <input type="file" name="img" onchange="uploadFile();" class="upload"/> </div> </form> <h3>预览</h3> <div id = 'preview'> </div> </div> <script src="{% static 'js/jquery-1.12.4.js' %}"></script> <script> function uploadFile() { document.getElementById('iframe').onload = reloadIframe; document.getElementById('fm').submit(); } function reloadIframe() { var content = this.contentWindow.document.body.innerText; var obj = JSON.parse(content); //生成一个img标签 var tag = document.createElement('img'); tag.src = obj.data; //先清空上一次的照片,再添加新的照片路径 $('#preview').empty().append(tag); } </script> </body> </html>
二、Models补充
1、字段补充
AutoField(Field) - int自增列,必须填入参数 primary_key=True BigAutoField(AutoField) - bigint自增列,必须填入参数 primary_key=True 注:当model中如果没有自增列,则自动会创建一个列名为id的列 from django.db import models class UserInfo(models.Model): # 自动创建一个列名为id的且为自增的整数列 username = models.CharField(max_length=32) class Group(models.Model): # 自定义自增列 nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) SmallIntegerField(IntegerField): - 小整数 -32768 ~ 32767 PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField) - 正小整数 0 ~ 32767 IntegerField(Field) - 整数列(有符号的) -2147483648 ~ 2147483647 PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField) - 正整数 0 ~ 2147483647 BigIntegerField(IntegerField): - 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807 BooleanField(Field) - 布尔值类型 NullBooleanField(Field): - 可以为空的布尔值 CharField(Field) - 字符类型 - 必须提供max_length参数, max_length表示字符长度 TextField(Field) - 文本类型 EmailField(CharField): - 字符串类型,Django Admin以及ModelForm中提供验证机制 IPAddressField(Field) - 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制 GenericIPAddressField(Field) - 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6 - 参数: protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6" unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启刺功能,需要protocol="both" URLField(CharField) - 字符串类型,Django Admin以及ModelForm中提供验证 URL SlugField(CharField) - 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号) CommaSeparatedIntegerField(CharField) - 字符串类型,格式必须为逗号分割的数字 UUIDField(Field) - 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证 FilePathField(Field) - 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能 - 参数: path, 文件夹路径 match=None, 正则匹配 recursive=False, 递归下面的文件夹 allow_files=True, 允许文件 allow_folders=False, 允许文件夹 FileField(Field) - 字符串,路径保存在数据库,文件上传到指定目录 - 参数: upload_to = "" 上传文件的保存路径 storage = None 存储组件,默认django.core.files.storage.FileSystemStorage ImageField(FileField) - 字符串,路径保存在数据库,文件上传到指定目录 - 参数: upload_to = "" 上传文件的保存路径 storage = None 存储组件,默认django.core.files.storage.FileSystemStorage width_field=None, 上传图片的高度保存的数据库字段名(字符串) height_field=None 上传图片的宽度保存的数据库字段名(字符串) DateTimeField(DateField) - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] DateField(DateTimeCheckMixin, Field) - 日期格式 YYYY-MM-DD TimeField(DateTimeCheckMixin, Field) - 时间格式 HH:MM[:ss[.uuuuuu]] DurationField(Field) - 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型 FloatField(Field) - 浮点型,小数位越多,约不精确,小数建议使用下面字段 DecimalField(Field) - 10进制小数 - 参数: max_digits,小数总长度 decimal_places,小数位长度 BinaryField(Field) - 二进制类型