首页 > 其他分享 >django ORM查询优化,事务,ajax

django ORM查询优化,事务,ajax

时间:2022-12-19 20:01:23浏览次数:40  
标签:obj objects models res django ajax ORM print 查询

ORM查询优化,事务,ajax

内容概要

  • Q查询进阶操作
  • ORM查询优化
  • ORM事务操作
  • ORM常用字段类型
  • ORM常用字段参数
  • ORM三种创建多对多的方式
  • Ajax请求

内容详细

Q查询进阶操作,默认and连接

from django.db.models import Q

q_obj = Q()
# q_obj.connector = 'or'
q_obj.children.append(('pk', 1))  # 默认连接符是and
q_obj.children.append(('publish_id',1))
res = models.Book.objects.filter(q_obj)
print(res)

image

from django.db.models import Q
q_obj = Q()
q_obj.connector = 'or'  # 修改连接符 为or
q_obj.children.append(('publish__gt', 2))
q_obj.children.append(('title__contains','三国'))#支持添加多个
res = models.Book.objects.filter(q_obj) # 查询对象支持填写Q对象
print(res)

image

ORM查询优化

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

    res = models.Book.objects.only('title','price').all()
    print('123')  # 按照以往的经验代码走到之这里上面的肯定就执行完毕了
    

    image

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

    res = models.Book.objects.only('title','price').all()
    print('123')  # 按照以往的经验代码走到之这里上面的肯定就执行完毕了
    print(res)
    

    image

  3. only与defer

only

数据对象+含有指定字段对应的数据

点括号内存在的字段

res = models.Book.objects.only('title','price')
print(res)  # 这里如果放在for循环queryset上面打印就会先查一下数据分页处理,然后下面for循环查的时候直接查完,不在分页
for obj in res:
    print(obj.price)  # 点上面填写的字段时候只会查一次数据库

image

不会每次查询

点括号内不存在的字段

res = models.Book.objects.only('title','price')
for obj in res:
    print(obj.publish)  # 点括号内不存的字段时候,每点一次,就查询一次sql语句

image

会每次查询

defer

点括号内存在的字段

res = models.Book.objects.defer('title','price')
for obj in res:
    print(obj.title)  # 点括你有的字段,每点一次查询一次

image

点括号内不存的字段

res_query = models.Book.objects.defer('title','price')
for obj in res_query:
    print(obj.pk)  # 点括号内不存在的字段,只查询一次

image

点击外键字段在括号内

res_query = models.Book.objects.defer('title','price','publish')
for obj in res_query:

    print(obj.publish)  # 在点击外键时候,外键在括号内,查询次数根据子查询在查一遍,相当于元数据的一倍

image

点击外键字段不在括号内

res_query = models.Book.objects.defer('title','price')
for obj in res_query:
    print(obj.publish) # 点外键不在括号内时,只查询数据个数次数

image

only与defer小总结:

使用only时,点的字段在括号内,就只查询一次SQL语句,点的字段不在括号内,就会每次查询都走SQL语句

使用defer时,点的字段在括号内,每次查询都走SQL语句,点的字段不在括号内,就只走一次SQL语句

不能放多对多字段

res_query = models.Book.objects.select_related('authors')  # 只能放外键字段,并且不能放多对多字段
print(res_query)

image

先连表后查询封装

res_query = models.Book.objects.select_related('publish')  # 括号内只能使用一对对外键和者,一对一外键
for obj in res_query:
    print(obj.publish.name)  # 底层使用的连表操作,执行走一次SQL语句

image

res_query = models.Book.objects.prefetch_related('authors') # 括号内所有外键都可使用
for obj in res_query: # 底层使用的是子查询操作
    print(obj.authors.all())  #查询字段值按照ORM跨表查询
    print(obj.title)

image

ORM事务操作

  1. 事务的四大特性(ACID)

    原子性
    一致性
    隔离性
    持久性

  2. 相关SQL关键字
    start transactions;
    roll back;
    commit;
    save point;

  3. 相关重要概念
    脏读,不可重复读,幻读,mvcc多版本控制、

再没有开启事务时,只要执行sql成功,下面错误不影响上面sql语句

def transcation(request):
    models.Publsh.objects.create(name='哈哈哈',address='1231')
    print('执行SQL完毕')
    asdasdasdas
    return HttpResponse('123')

image

django orm提供了至少三种开启事务的方式

方式1:配置文件数据相关添加键值对 全局有效

'ATOMIC_REQUESTS': True,  # 每次请求所涉及到的ORM操作为一个事务
    
    
def transcation(request):
    models.Publsh.objects.create(name='撒旦胡卡',address='123')
    print('执行SQL完毕')
    asdasdasdas
    return HttpResponse('123')

image

只要再一个视图函数中或者视图类中的一个请求中,都同属一个事务,只要出现错误就回滚到之前的状态

方式2:装饰 局部有效

@transaction.atomic  #局部有效
def transcation(request):
    models.Publsh.objects.create(name='撒旦胡卡', address='123')
    print('执行SQL完毕')
    asdasdasdas
    return HttpResponse('123')

image

方式3:上下文管理 局部有效

def ttt(request):
    print(123)
    with transaction.atomic():
        models.Publsh.objects.create(name='撒旦胡卡', address='123')
        print('执行SQL完毕')
        asdasdasdas
        return HttpResponse('123')

image

ORM常用字段类型

class Test1(models.Model):
    id = models.AutoField(primary_key=True)  # 主键字段 int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列。
    var1 = models.CharField(max_length=32)  # 字符串字段,必须指定max_length 字符类型,必须提供max_length参数, max_length表示字符长度。
    var2 = models.IntegerField()  # 整数字段最大11位 一个整数类型,范围在 -2147483648 to 2147483647。(一般不用它来存手机号(位数也不够),直接用字符串存,)
    var3 = models.BigIntegerField()  # 大整数字段
    var4 = models.DecimalField(max_digits=8, decimal_places=2)  # 小数字段
    var5 = models.DateTimeField(auto_now_add=True)  # 年月日时分秒,时间字段
    var6 = models.DateField(auto_now=True)  # 年月日,时间字段
    var7 = models.BooleanField()  # 布尔字段 传布尔值自动存0或1
    var8 = models.TextField()  # 存储大段文本 无需传入max_length参数
    var9 = models.EmailField()  # 储存邮件格式数据
    var10 = models.FileField()  # 传文件对象 自动保存到提前配置好的路径下并存储好该路径信息

ORM还支持用户自定义字段类型

class MyCharField(models.Field):

    def __init__(self,*args,**kwargs):
        super().__init__(*args,**kwargs)


    def db_type(self, connection):
        return 'char(%s)' % self.max_length


class Usera(models.Model):
    name = models.CharField(max_length=32)
    info = MyCharField(max_length=10)

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相似

Ajax

异步提交 局部刷新

ajax不是一门新的技术并且有很多版本 我们目前学习的是jQuery版本(版本无所谓 本质一样就可以)

AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。

  • 同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
  • 异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。

基本语法

<P><input type="text" id="input1">+<input type="text" id="input2">=<input type="text" id="input3"></P>
<input type="submit" id="sub">


<script>

    let sub = $('#sub').click(function () {

        var in1 = $('#input1').val()
        var in2 = $('#input2').val()
        console.log(in1,in2)

        $.ajax({
        url:'',  <!--后端地址 三种填写方式 与form标签action一致-->
        type:'post',  // 请求方式 默认也是get
        data:{'var1':in1,'var2':in2},  //发送的数据
        success:function (args) {  //后端返回结果之后自动触发 args接收后端返回的数据
            $('#input3').val(arg)
        }
        })
    })
</script>

Content-Type

urlencoded

ajax默认的编码格式、form表单默认也是
数据格式 xxx=yyy&zzz=bbb&aaa=ccc
django后端会自动处理到request.POST中

formdata

django后端针对普通的键值对还是处理到request.POST中
但是针对文件会处理到request.FILES中

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>
后端还是从request.FILES中获取文件

标签:obj,objects,models,res,django,ajax,ORM,print,查询
From: https://www.cnblogs.com/clever-cat/p/16992960.html

相关文章

  • Ajax请求 content_type ajax发送Fromdata对象
    目录Ajax请求入门ajax实现简单计算器content_typeurlencodefromdataapplication/json自定义request.JSONajax发送Fromdata对象Ajax请求入门异步提交局部刷新ajax不是一......
  • ORM的一些尾巴和Ajax的基础
    今日内容详细Q查询进阶操作使用Q查询记得先导入fromdjango.db.modelsimportQ#1.先产生Q对象q_obj=Q()#2.默认多个条件的连接条件是and可以修改为orq_obj.c......
  • Q查询进阶操作 ORM查询优化 only与defer select_related与prefetch_related ORM事务 O
    目录Q查询进阶操作children.append图书查询功能ORM查询优化惰性查询自动分页limitonly与deferonlydeferselect_related与prefetch_relatedselect_relatedprefetch_related......
  • Django之模型层ORM事务操作、ORM常用字段及参数
    复习:1.事务的四大特性(ACID)原子性、一致性、隔离性、持久性2.相关SQL关键字 starttransaction; rollback; commit; savepoint;3.相关重要概念 脏读、幻读、......
  • WaitForSingleObject与WaitForMultipleObjects用法详解
    在多线程下面,有时候会希望等待某一线程完成了再继续做其他事情,要实现这个目的,可以使用WindowsAPI函数WaitForSingleObject,或者WaitForMultipleObjects。这两个函数都会等待......
  • formly-form 动态表单
    动态表单库https://github.com/ngx-formly/ngx-formly安装ngadd@ngx-formly/schematics--ui-theme=ng-zorro-antd@ngx-formly/ng-zorro-antd选择UIbootstr......
  • EBS挂载FORM详细步骤
    上传fmb文件编译到指定目录,具体编译到哪里,可以在applicationdeveloper职责下的应用产品->注册查看F11搜索,搜索%SECOM%,记下基本路径,下一步会用到3编译登录服务器,进......
  • Q查询进阶 ORM查询优化 ORM事物操作 ORM常用字段及字段参数 Ajax请求
    目录Q查询进阶操作ORM查询优化1.ORM的查询默认都是惰性查询2.ORM的查询自带分页处理3.only与deferonlydefer4.select_related与prefetch_relatedselect_related连表查询pr......
  • django简易图书管理系统
    图书管理系统项目前期准备在pycharm中创建新项目配置默认设置文件创建db1216库配置默认设置文件表结构设计图书表(书名(CharField),图书价格(DesimalField),图......
  • django-Ajax
    Ajaxajax不是一门新的技术并且有很多版本我们目前的是jQuery版本(版本无所谓本质一样就可以)Ajax的特点:异步提交,局部刷新基本语法: $.ajax({url:'',//后......