目录
Q查询进阶操作
from django.db.models import Q
q_obj = Q() # 1.产生q对象
q_obj.connector = 'or' # 默认多个条件的连接是and可以修改为or
q_obj.children.append(('pk', 1)) # 2.添加查询条件
q_obj.children.append(('price__gt', 2000)) # 支持添加多个
res = models.Book.objects.filter(q_obj) # 查询支持直接填写q对象
print(res)
ORM查询优化
django orm查询默认都是惰性查询,只有orm的语句在后续的代码中真正需要使用的时候才会执行。还自带limit分页功能,是为了减轻数据库端以及服务端的压力。
ORM查询优化之only与defer
res = models.Book.objects.only('title','price') # queryset [数据对象、数据对象]
for obj in res:
print(obj.title)
print(obj.price)
print(obj.publish_time)
only会将括号内填写的字段封装成一个个数据对象,对象在点击括号内的字段的时候不会再走数据库查询,但是对象也可以点击括号内没有的字段,只不过每次都会走数据库。
res = models.Book.objects.defer('title', 'price') # queryset [数据对象、数据对象]
for obj in res:
print(obj.title)
print(obj.price)
print(obj.publish_time)
defer与only刚好相反,数据对象点括号内出现的字段,每次都会走数据库查询;
数据对象点括号内没有的字段,不会走数据库查询。
ORM查询优化之select_related与prefetch_related
res = models.Book.objects.select_related('authors')
for obj in res:
print(obj.publish.name)
select_related括号内只能接收外键字段自动连表,得出的数据对象在点表中数据的时候都不会再走数据库查询。
res = models.Book.objects.prefetch_related('publish')
for obj in res:
print(obj.publish.name)
prefetch_related底层其实是子查询,将查询之后的结果一次性封装到数据对象中,用户在使用的时候是感觉不出来的。
ORM事务操作
MySQL事务:四大特性(ACID),原子性,一致性,独立性,持久性。一个事务是一个整体,要么同时成功要么同时失败。
事务隔离级别:
1.read uncommitted(未提交读)
事务中的修改即使没有提交,对其他事务也都是可见的,事务可以读取未提交的数据,这一现象也称之为"脏读"
2.read committed(提交读)
大多数数据库系统默认的隔离级别
一个事务从开始直到提交之前所作的任何修改对其他事务都是不可见的,这种级别也叫做"不可重复读"
3.repeatable read(可重复读) # MySQL默认隔离级别
能够解决"脏读"问题,但是无法解决"幻读"
所谓幻读指的是当某个事务在读取某个范围内的记录时另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录会产生幻行,InnoDB和XtraDB通过多版本并发控制(MVCC)及间隙锁策略解决该问题
4.serializable(可串行读)
强制事务串行执行,很少使用该级别
mysql开启事务:start transcation;
mysql回滚事务:rollback;
mysql停止事务:commit;
mysql保留点:savepoint
django orm提供了至少三种开启事务的方式:
方式1:配置文件数据库相关添加键值对 全局有效
"ATOMIC_REQUESTS": True每次请求所涉及到的orm操作同属于一个事务
方式2:装饰器 局部有效
from django.db import transaction
@transaction.atomic
def index():pass
方式3:with上下文管理 局部有效
from django.db import transaction
def reg():
with transaction.atomic():
pass
ORM常用字段类型
ORM字段和mysql里字段的对应关系。
关系字段
ForeignKey() OneToOneField() ManyToManyField()
ORM还支持自定义字段
class MyCharField(models.Field):
def __init__(self, max_length, *args, **kwargs):
self.max_length = max_length
super().__init__(max_length=max_length, *args, **kwargs)
def db_type(self, connection):
return 'char(%s)' % self.max_length
class User(models.Model):
name = models.CharField(max_length=32)
info = MyCharField(max_length=64)
ORM常用字段参数
choices:当字段数据的可能性是可以完全列举出来的时候应该考虑使用该参数
class User(models.Model):
name = models.CharField(max_length=32)
info = MyCharField(max_length=64)
# 提前列举好对应关系
gender_choice = (
(1, '男性'),
(2, '女性'),
(3, '其他'),
)
gender = models.IntegerField(choices=gender_choice,null=True)
user_obj = User.objects.filter(pk=1).first()
user_obj.gender
user_obj.get_gender_display()
to 关联表
to_field 关联字段(不写默认关联数据主键)
on_delete 当删除关联表中的数据时,当前表与其关联的
1、models.CASCADE
级联操作,当主表中被连接的一条数据删除时,从表中所有与之关联的数据同时被删除
2、models.SET_NULL
当主表中的一行数据删除时,从表中所有与之关联的数据的相关字段设置为null,此时注意定义外键时,这个字段必须可以允许为空
3、models.PROTECT
当主表中的一行数据删除时,由于从表中相关字段是受保护的外键,所以都不允许删除
4、models.SET_DEFAULT
当主表中的一行数据删除时,从表中所有相关的数据的关联字段设置为默认值,此时注意定义外键时,这个外键字段应该有一个默认值
5、models.SET()
当主表中的一条数据删除时,从表中所有的关联数据字段设置为SET()中设置的值,与models.SET_DEFAULT相似,只不过此时从表中的相关字段不需要设置default参数
6、models.DO_NOTHING
什么都不做,一切都看数据库级别的约束,注数据库级别的默认约束为RESTRICT,这个约束与django中的models.PROTECT相似
Ajax异步提交
Ajax:页面不刷新的情况下可以与后端进行数据交互。特点:异步提交,局部刷新。
Ajax不是一门全新知识,本质就是一些js代码,我们学习Ajax直接使用jQuery封装之后的版本(语法更加简单),使用Ajax的前提必须要引入jQuery文件。
学习Ajax一定要能够发现与form表单提交数据的区别。
Ajax:提交数据页面不用刷新,原始数据还在,处理数据的过程中不影响页面其他操作
form:表单提交数据页面刷新,原始数据不在,并且处理数据的过程中无法做其他操作
基础语法
$.ajax({
url:'', // 后端地址 三种填写方式 与form标签的action一致
type:'post', // 请求方式 默认也是get
data:{'v1':v1Val, 'v2':v2Val}, // 发送的数据
success:function (args) { // 后端返回结果之后自动触发 args接收后端返回的数据
$('#d3').val(args)
}
})
数据编码格式
请求体中携带编码格式:Content-Type: ...
django针对不同编码方式对应的数据格式会采用不同的处理策略
from表单默认发送的编码格式
1.urlencoded
ajax默认的编码格式、form表单默认也是
数据格式 xxx=yyy&uuu=ooo&aaa=kkk
django后端会自动处理到request.POST中
from表单发送文件
2.formdata
django后端针对普通的键值对还是处理到request.POST中 但是针对文件会处理到request.FILES中
ajax默认发送的编码格式
Content-Type: application/x-www-form-urlencoded
数据格式: name=jason&password=123&hobby=read
django后端统一处理到request.POST中
ajax发送json格式数据
编码格式:urlencoded
数据格式:json格式
django后端不会做任何处理、在request.body中存储(bytes类型)、需要我们自己处理
3.application/json
form表单不支持 ajax可以
<script>
$('#d1').click(function () {
$.ajax({
url:'',
type:'post',
data:JSON.stringify({'name':'jason','age':18}), // 千万不要骗人家
contentType:'application/json',
success:function (args) {
alert(args)
}
})
})
</script>
后端需要从request.body中获取并自己处理
ajax携带文件数据
<script>
$('#d3').click(function () {
// 1.先产生一个FormData对象
let myFormDataObj = new FormData();
// 2.往该对象中添加普通数据
myFormDataObj.append('name', 'jason');
myFormDataObj.append('age', 18);
// 3.往该对象中添加文件数据
myFormDataObj.append('file', $('#d2')[0].files[0])
// 4.发送ajax请求
$.ajax({
url:'',
type:'post',
data:myFormDataObj,
// ajax发送文件固定的两个配置
contentType:false,
processData:false,
success:function (args){
alert(args)
}
})
})
</script>
标签:obj,models,查询,ajax,ORM,常用字,数据
From: https://www.cnblogs.com/wxlxl/p/17020631.html