首页 > 其他分享 >Q查询进阶 ORM查询优化 ORM事物操作 ORM常用字段及字段参数 Ajax请求

Q查询进阶 ORM查询优化 ORM事物操作 ORM常用字段及字段参数 Ajax请求

时间:2022-12-19 17:55:56浏览次数:37  
标签:obj models res 查询 ORM 常用字 SQL

目录

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)

查询条件的左侧 能够将查询条件的左侧由变量名或字段名变字符串

image

先用Q产生一个对象 而Q其实就一个类 类加括号就是在实例化对象 那么q_obj就成查询条件了 默认是and关系

image

那么也支持改成or关系

image

这样就可以实现与用户交互 前端返回的是字符串类型 就可以编写简易的搜索框查询功能

image

ORM查询优化

1.ORM的查询默认都是惰性查询
2.ORM的查询自带分页处理
3.only与defer
	'''数据对象+含有指定字段对应的数据'''
    # res = models.Book.objects.only('title', 'price')
    # print(res)  # queryset [数据对象、数据对象]
    # for obj in res:
        # print(obj.title)  # 点击括号内填写的字段 不走SQL查询
        # print(obj.price)
        # print(obj.publish_time)  # 可以点击括号内没有的字段获取数据 但是会走SQL查询
        
    res = models.Book.objects.defer('title', 'price')
    # print(res)  # queryset [数据对象、数据对象]
    for obj in res:
        # print(obj.title)  # 点击括号内填写的字段 走SQL查询
        # print(obj.price)
        print(obj.publish_time)  # 点击括号内没有的字段获取数据 不走SQL查询
4.select_related与prefetch_related
	 # res = models.Book.objects.all()
    # for obj in res:
    #     print(obj.publish.name)  # 每次查询都需要走SQL
    # res = models.Book.objects.select_related('authors')  # 先连表后查询封装
    # res1 = models.Author.objects.select_related('author_detail')  # 括号内不支持多对多字段 其他两个都可以
    # print(res1)
    # for obj in res:
    #     print(obj.publish.name)  # 不再走SQL查询

    res = models.Book.objects.prefetch_related('publish')  # 子查询
    for obj in res:
        print(obj.publish.name)

1.ORM的查询默认都是惰性查询

image

如上图中res都是灰色 没有执行 针对查询 只要不用 就不会执行这样就可以节省效率

用了就会执行

image

2.ORM的查询自带分页处理

当在查数据比较庞大的时候 假如有几亿条数据 那么在查询的时候就得做分页处理 ORM中查询是默认分页

image

PS:以后自己在写SQL的时候 在对一张表做查询 表数据比较庞大的时候 为防止崩溃 最好是加上limit做防范

3.only与defer

only

all就是把表里面所有的数据都封装到对象里面去 然后对象去点里面的数据就不用再走数据库查询

只执行了一条sql语句

image

那如果只想要书和价格呢?

用values拿指定字段对应的数据 那么得到的是列表套字典 并不能拥有对象点的方式

想要i能够点书名和价格 结果报错 手里拿的字典没法点 报错

image

多个对象里面含有只有指定的多个字段数据 其他的没有 这时候就要用到only了

就是all与values结合 既拥有的all对象点的方式也拥有了values拿到指定字段的数据

如图得到的就是列表套对象

image

就能拿到指定的字段数据 点only括号内的不走sql

SQL也只执行了一次

image

点括号外的走SQL

image

将only括号里面的数据封装到对象里面 当在点括号里面的数据是不会走SQL查询 而如果是点的是括号里没有填写的字段 可以拿到数据 但每点一次 都会执行一次SQL数据库查询

image

defer

defer与only相反 括号内的走sql 括号外的不走

点defer括号里面的 就会走SQL查询

image

点defer括号外的其他字段 就不走SQL查询

image

如下图的查询是把书籍的数据封装到了对象中 书籍对象点其他除书以外其他的字段就每点一次就会得执行一次SQL查询

image

如何优化查询次数 以及查询时间呢?
用到select_related 连表查询

image

提前封装好了 就不用再走SQL查询了 也只走一句

image

不允许填写多对多虚拟字段 只能是一对一 一对多

否则报错

image

外键字段不允许填写多对多虚拟字段 只能是一对一或一对多

    res = models.Book.objects.prefetch_related('publish')  # 子查询
    for obj in res:
        print(obj.publish.name)

把书所有的书籍先查出来基于书里面的publish_id再到出版社里面把对应数据查找出来

只会执行两条SQL 先执行一条把这一条的结果当做另外一条的条件 用的时候感觉不出来

image

ORM事物操作

"""
1.事务的四大特性(ACID)
	原子性、一致性、隔离性、持久性
2.相关SQL关键字
	start transaction;
	rollback;
	commit;
	savepoint;
3.相关重要概念
	脏读、幻读、不可重复读、MVCC多版本控制...
"""
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

三种开启事物的方式

settings配置中有 网址记录了数据库相关操作
image

方式1:配置文件数据库相关添加键值对

       "ATOMIC_REQUESTS": True每次请求所涉及到的orm操作同属于一个事务

全局事物开启 全局有效

默认每一次请求所涉及到的orm操作同属于一个事务

要么都成功要么都失败

image

如下报错就会回滚

image

极限情况 :

当返回的不是一个response对象时 也是会执行成功的

只要到return就执行成功 即使会报错 表数据也添加成功了

image

方式2:装饰器

       from django.db import transaction
       @transaction.atomic
       def index():pass	

需要导一个transaction模块

局部有效 局部开启针对某个视图函数 image

被装饰器修饰的视图函数就属于一个事物

image

表数据添加成功

image

极限情况:

当返回的不是一个response对象时 也是会执行成功的

image

image

3.with上下文管理

局部有效 也是需要导一个transaction模块

image

with里面的报错自动回滚

如下图中在with里面报错就会自动回滚

image

添加成功:

image

ORM常用字段

AutoField
	primary_key=True
CharField
	max_length
IntegerField
BigIntergerField
DecimalField
	max_digits decimal_places
DateField
	auto_now auto_now_add
DateTimeField
	auto_now auto_now_add
BooleanField
	传布尔值自动存0或1
TextField
	存储大段文本
EmailField
	存储邮箱格式数据
FileField
	传文件对象 自动保存到提前配置好的路径下并存储该路径信息

image-20221219104113630

什么文件都可以

image-20221219104245842

支持自定义字段类型

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)

字段类型都是一个个的类

image

重新改写继承

image

image

ORM字段类型与原生SQL的对应

image-20221219104914036

ORM字段参数

外键多了就增强了耦合度 就不一样解耦合 所以外键一般是靠代码逻辑来建立

primary_key 	主键
verbose_name	注释
max_length		字段长度
max_digits     小数总共多少位
decimal_places	小数点后面的位数
auto_now		每次操作数据自动更新事件
auto_now_add	首次创建自动更新事件后续不自动更新
null			允许字段为空
default			字段默认值
unique			唯一值
db_index		给字段添加索引
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相似

choices

当个某一个字段能够被完全的列举出来时

image

image

除里面指定的填啥就是啥

如下图填写的4就是4了 而1 2 3指定的就是男性 女性 其他

image

固定语法get_xxx_display()

Ajax请求

异步提交 局部刷新

场景:在没有点提交 都会自动校验

image

Async就是异步的意思

目前学的是jQuery版本

如下图 在点提交让它不刷新 原来的数据还在

image

必须要导:

image

image

image

写js代码

image

异步回调函数

image

标签:obj,models,res,查询,ORM,常用字,SQL
From: https://www.cnblogs.com/xiao-fu-zi/p/16992752.html

相关文章