ORM查询优化
only与defer查询优化
减轻数据库的压力
only:
only括号内放
字段,查询结果是一个列表套一个个数据对象
这些数据对象点括号的字段属性不会再查询数据库,直接就是对象获取属性
也支持点击括号内没有的字段,但是每点击一次就会重新走一次数据库查询
缺点:效率极低
实例:
res = models.Book.objects.only('title')
#print(res) #拿到对象 数据库语句只走一次
for i in res:
print(i.title) #拿到数据所有书名 走一次数据库语句
print(i.price) #走5次数据库查询语句,第1次是总体的查询语句,后面4条是4条书籍字段的语句
defer:
实例:
res = models.Book.objects.defer('title')
#print(res) #打印的结果是列表套对象,走一条数据库语句
for i in res:
print(i.title) #走5次数据库查询语句,第1次是总体的查询语句,后面4条是4条书籍字段的语句
print(i.price) #点price 走一次数据语句
总结:only与defer互为反关系
defer括号内放什么字段 查询出来的对象就没有该字段
如果你要点击 每点击一次就要重新走一次数据库
而你如果点击了非括号内的字段 就不会走数据库 仅仅是对象属性的操作
select_related与prefetch_ralated
select_related:
实例:
res = models.Book.objects.all()
#print(res) #只走一次数据库语句
for i in res:
print(i.title) #只走一次数据库语句
print(i.publish) #正向查询(按字段) #走5次数据库查询语句,第1次是总体的查询语句,后面4条是4条出版社字段的语句 #多次查询会对数据库造成压力
实例:使用select_related优化实例
特点:
- select_related括号内只能放外键字段,并且外键字段的类型只能是一对多 或者 一对一 不能是多对多的
- 内部是自动联表操作 会将括号内外键字段所关联的表与当前表自动拼接成一张,然后将表中的数据一个个查询出来封装成一个个的对象
- 可以放多个外键字段,逗号隔开,会将多个外键字段关联表与当前的表拼成一个大的表
- 类似于left join , right join
优点:
跨表不用重复走数据库语句 ,减轻数据库的压力
res = models.Book.objects.select_related('publish')
#print(res) # 走一条数据库语句
for i in res:
print(i.title) # 走一条数据库语句
print(i.publish) # 走一条数据库语句
prefetch_ralated:
特点:
- prefetch_ralated内部是子查询,会自动帮你按步骤查询多张表,然后将程序的结果封装到对象中,给用户的感觉还是联表操作
- 括号内支持传多个外键字段,没有类型限制,可以是多对多字段,每放一个外键字段,就多走一条sql语句,就多查询一张表
实例:
res = models.Book.objects.prefetch_related('publish','authors')
#print(res) # 走两条数据库语句
for i in res:
print(i.title) # 走两条数据库语句
print(i.publish) # 走两条数据库语句
区别:
select_related 耗时:在联表上
prefetch_related 耗时: 查询的次数上 上千张表推荐使用
MTV与MVC模型
MTV:django自称是MTV框架,本质是MVC框架
MTV:可以拆分成
M:models
T:templates
V:views
MVC:
M:models
T:templates
C: controllar 路由匹配
choices参数
在将choices参数之间,我们先来回顾一下Django ORM创建表类中字段如何创建的把,是不是下面这样
# 举例这是一张用户基本信息表
class UserInfo(models.Model):
username = CharField(max_length=32)
age = IntegerField() # 整型字段不要传max_length参数哦----特别注意
gender = CharField(max_length=2)# 用户性别
通过上面的userinfo表,我们是否可以想一下,在用户性别字段中,人类的性别好像只有两种表示方式,男/女,那这样,我们如果有100万条用户信息,而这100万条用户的性别就这么巧有90万都是女。
这个时候,就造成了问题,既然我们这个字段的描述信息,只需要两种描述就能完成这个用户字段在性别的描述,我们为什么不想一种方便简洁的形式去描述每一个用户的性别呢?
这个时候,不知道还是否记得,有没有什么数据类型是只有两种表现形式的呢?(布尔值?),没错就是布尔值,布尔值大家是否还记得(0:false / 1:True)。
这是一种方法,但是在这种情况下,很遗憾我们不需要用布尔值这种方式,这就引出了choices参数
我们依然是用数字来记录gender这个用户性别字段的描述,大家学过数据库就知道,能用整型存储的信息,为什么要用字符型呢?很明显,是因为整型比字符型占的空间小。
注意:并不是所有的这种仅仅用几个描述就能完成队大量数据的描述,都去用数字的,此处只是用gender字段为例!!
choices 参数的概念:它是一种以列表 / 元组的型式,里面嵌套着少数几个小元组的方式,表示一种对应关系
Ajax简介
Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。
Ajax = 异步 JavaScript 和 XML 或者是 HTML(标准通用标记语言的子集)。
Ajax 是一种用于创建快速动态网页的技术。
Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
优点:通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。(这一特点让用户感觉在不知不觉中完成请求响应的过程)
XML也是一门标记语言
该语法应用场景
-
写配置文件
-
可以写前端页面(odoo框架中 erp)
每家公司都会有属于自己公司独有的内部管理软件,专门用来开发企业内部管理软件 框架 odoo
odoo框架内部功能实现全部依赖于python2
薪资计算
我们在学的时候只学JQuery封装好的方法 不需要掌握原生js版本在使用的时候一定要先导入jQuery括号内记得手动输入一个大括号: $.ajax({ })
ajax基本语法:
$.ajax({
url:'', //数据提交的后端地址,不写就是往当前页面提交,也可以写后缀,全称,跟actions一样
type:'post', //提交方式 默认是get请求
data:{'i1':$('#d1').val(),'i2':$('#d2').val()}, //提交的数据
success:function(data){ //形参data就是异步提交之后后端返回结果
$('#d3').val(data) //回调机制需要做的事情
}
})
一旦你使用了ajax 必知必会三板斧都不再作用于页面 而是与ajax交互
a标签href参数 get请求
form表单 get/post
ajax get/post
前端和后端数据编码格式
前后端交互式一个数据编格式 针对不同的数据 后端会进行不同的处理
request.POST
request.FILES
- urlencoded
- formdata
- application/json
form表单发送数据的编码格式
Content-Type: application/x-www-form-urlencoded
-
form表单默认的编码方式是urlencoded
urlencoded所对应的数据格式 username=jason&password=123 django后端针对urlencoded数据 会自动解析并且帮你封装到request.POST中
-
form表单发送文件 编码格式Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryhjKCHQHDmcE62iMQ
针对formdata格式的数据,你在浏览器上是无法看到的
django后端只要你的数据满足urlencode格式 username=jason&password=123 就会自动帮你解析到request.POST中 如果你是一个文件对象django后端也会自动识别帮你放到request.FILES中
-
form表单无法发送json格式的数据 你要想传 你只能借助于ajax
ajax发送json格式数据
ajax发送数据的编码格式
ajax能够发送
urlencoded
formdata
application/json
Content-Type: application/x-www-form-urlencoded; charset=UTF-8ajax默认的编码格式也是urlencoded 也就意味着后端django也是将数据解析到request.POST中
在涉及到前后端交互的时候 你一定要做到数据的格式与编码格式一致
千万不要欺骗人家 数据是一种格式 请求头里面是另外一种格式
ajax发送json数据格式
dumps stringify
loads parse
Content-Type: application/json
{"username":"jason","password":"123"}
django后端针对json格式的数据 不会做任何的处理 数据怎么来的 只会原封不动的放到request.body中,需要自己动手处理
$('#d1').click(function () {
$.ajax({
url:'',
type:'post',
contentType:'application/json', # 1.注意点1
data:JSON.stringify({'username':'jason','password':'123'}), # 2.注意点2
success:function (data) {
alert(123)
}
})
})
ajax发送文件格式数据
借助于内置对象 new
该对象既可以携带文件数据 同样也支持普通的键值对
$('#d1').click(function () {
// 先生成一个内置对象
var MyFormData = new FormData();
//1.先添加普通的键值对
MyFormData.append('username','json')//添加了一组普通的键值对
MyFormData.append('password','123');
//2.添加文件数据
MyFormData.append('myfile',$('#d2')[0].files[0];)//如何获取input框中文件对象$('#d1')[0].files[0];)
$.ajax({
url:'',
type:'post',
data:MyFormData, # 1
//发送文件必须要指定的两个参数
contentType:false//不适用任何编码 MyFormData对象内部自带编码 django后端能够识别 # 2
procesData:false,//不要处理数据 #3
success:function(data){
}
})
})
序列化
drf django restframework
from app01 import models
from django.core import serializers
# 序列化目的 将数据整合成一个大字典形式 方便数据的交互
def zzz(request):
user_queryset = models.User.objects.all()
# [{username:...,password:...,hobby:...,},{},{},{}]
# user_list = []
# for data in user_queryset:
# user_list.append(
# {'username':data.username,
# 'password':data.password,
# 'gender':data.get_gender_display(),
#
# }
# )
res = serializers.serialize('json',user_queryset)
return HttpResponse(res)
循环链表
循环链表是另一种形式的链式存贮结构。它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。
(1)单循环链表——在单链表中,将终端结点的指针域NULL改为指向表头结点或开始结点即可。
(2)多重链的循环链表——将表中结点链在多个环上。
优点:从表中任意一结点出发均能可找到表中的其他结点
判断空链表条件是:
head==head->next;
rear==rear->next;
尾指针
用尾指针rear表示的单循环链表对开始结点a1和终端结点an查找时间都是O(1)。而表的操作常常是在表的首尾位置上进行,因此,实用中多采用尾指针表示单循环链表。带尾指针的单循环链表可见下图。
实例:在链表上实现两个线性表(a1...an)和(b1...bn)连成一个线性表(a1...an,b1...bn)的运算
LinkListConnect(LinkListA,LinkListB)
{//假设A,B为非空循环链表的尾指针
LinkListp=A->next;//①保存A表的头结点位置
A->next=B->next->next;//②B表的开始结点链接到A表尾
free(B->next);//③释放B表的头结点
B->next=p;//④
returnB;//返回新循环链表的尾指针
}
注意:循环链表中的指针没有NULL
注意:由于循环链表中没有NULL,故涉及遍历操作时,其终止条件就不再像非循环链表那样判断p或p->next是否为空,而是判断他们是否等于头指针
循环条件:
单链表 单循环链表
p! = NULL -> p!= L
p!->next! = NULL -> p->next! = L
最后一个结点是指向头指针的