ORM增删改查(关联 | 聚合 | F/Q)&惰性机制 | Django开发

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ORM增删改查(关联 | 聚合 | F/Q)&惰性机制 | Django开发相关的知识,希望对你有一定的参考价值。

=======ORM========
1.创建表
    1.1 单表
    1.2 关联表
        一对一
        一对多
        多对多

2.操作表(行对象操作)
    2.1 增
        create;
            (1) models.Book.objects.create(title="python",price=12)
                dict = {"titile":"GO","price":45}
            (2) models.Book.objects.create()
            # 如果有外键
                1.一对多:
                # ForeignKey
                    <1> models.Book.objects.create(title="python",price=12,publish_id=1)
                    <2> models.Book.objects.create(title="python",price=12,publish=obj)
                        # 推荐
                2.多对多:
                # 自动创建第三张表;ManyToManyField;
                    ---------------------------------------正向查询
                    # 获取book这行数据的一个对象;
                    book = models.Book.objects.filter(id=2)[0]
                    # 获取一个对象序列,存放authors对象;
                    authors = models.Author.objects.filter(id__gt=2);
                    # 序列前加上*;
                    book.author.add(*authors) 
                    ----------------------------------------反向查询
                    author = models.Author.objects.filter(id=2)[0];
                    book = models.Book.objects.filter(id=2);
                    author.book_set.add(*books)
                # 手动创建第三张表;
                    class Book2Author(models.Model):
                        # 绑定两个一对多;
                        # ForeignKey来完成ManyToManyField;
                        author = models.ForeignKey("Author")
                        book = models.ForeignKey("Book")
                        # 绑定联合唯一索引;
                        # 按需添加;
                        class Meta:
                        unique_together=["author","book"]
                    # 视图中实例化表对象,添加行数据;
                    models.Book2Author.objects.create(
                        book_id = 2;
                        author_id = 3
                    )
                3.一对一:
                    OneToOneField():
                    # 通过一个ForeignKey,并且添加unique=True属性;

        save;
            (1)obj = Book(title="python",price=12)
                obj.save()
            (2)obj=Book()
                obj.title="GO"
                obg.price=45
                obj.save()

    2.2 删
        models.Book.objects.filter(id=2).delete()
        # 当删除这一行时,关联表中对应包含这个id的行会全部删除;
        # 级联删除;

    2.31.update
            # 仅适合在queryset对象(一个对象集合)下的操作,不能用get(id=2)
            Publisher.objects.filter(id=2).update(name=American publisher)
        2.save
            # save()会执行整列更新,效率要低一些;
            author=Author.objects.get(id=5)
            # 赋值
            author.name = Mike
            author.save()

    2.41.查询API
            <1>filter(**kwargs) # 筛选条件匹配;
            <2>all()
            <3>get(**kwargs) # 单个对象;
            <4>exclude(**kwargs) # 与筛选条件不匹配;
            # ------------------>> 根据上面操作之后的对象,再进行一下操作;
            <5>values(*field) # 得到的不是一系列model的实例化对象,而是一个可迭代的字典序列;
            <6>order_by(*field)
            <7>reverse() # 查询集反向排序;
            <8>distinct() # 查询集提出重复记录;
            <9>values_list(*field) # 返回元组序列;values()返回字典序列;
            <10>count() # 返回查询集中的对象数量;
            <11>first() # 返回第一条记录;
            <12>last() # 返回最后一条记录;
            <13>exists() # 判断查询集是否保存数据,返回布尔值;
3.惰性机制
    # 在创建查询集的时候不会执行sql语句!!!!!
    # 在对查询集进行操作(切片,迭代)的时候才会执行;(并且将这个操作数据存放在缓存中|Django缓存机制)
    1.通过在settings.py文件中添加一段代码,将执行sql语句的状态以日志的形式显示在终端;
    -------------------------------------------------
    LOGGING = {
        versoin:1,
        disable_existing_loggers:False,
        handlers:{
            console:{
                level:DEBUG,
                class:logging.StreamHandler,
            },
        },
        loggers:{
            django.db.backends:{
                handlers:[console],
                propagate:True,
                level:DEBUG,
            },
        }
    }
    -------------------------------------------------

    2.弊端
        <1> 比如在对查询集存在的判断,
        # if obj_set:会将所有数据存放在缓存中,增加Django运行的压力,浪费缓存空间;
        # 措施:exists()
            if obj_set.exists():
            # 经过数据库查询,只返回布尔值,不将数据库数据放入缓存;
        <2> 在迭代输出数据的时候,也会将数据存放在缓存;
        # 措施:迭代器
            if obj_set.iterator():
            # 用一个取一个;

4.关联查询
    4.1 正向查询|反向查询(对象形式查找)
        # 有两个表:book;publisher;
        # 在book中创建了一个关联publisher表的外键:publish = models.ForeignKey(‘Publisher‘)
        1.正向查询:
            # 根据book对象,查询publisher表中的author字段;
            # 直接通过Book下的关联字段,查询关联表的字段;
            obj = models.Book.objects.filter(title="GO")[0]
            print(obj.publisher.name)
        2.反向查询:
            obj = models.Publisher.objects.filter(name="人民出版社")[0]
            # book_set.all()
            print(obj.book_set.all().values(title).distinct())
        
    4.2 双下划线(__)查询
        1.单表查询
            <1>__lt=,__gt=
            <2>__in=[]
            <3>__contains=
            <4>__icontains= # 大小写不敏感的包含;
            <5>__range=[num1,num2] 范围
            <6>__startswith,__istartswith,__endswith,__iendswith;

        2.关联表多表查询
            # 双下划线可在关联查询的关联表中的字段!!!!!不管是filter还是values(查询还是显示);
            models.Publish.objects.filter(book__title="Python").values("name")
            ... ...
        
5.聚合查询|分组查询
    5.1 aggregate(*args,**kwargs)
        # 通过对QuerySet进行计算,返回一个聚合值的字典;
        from django.db.models import Avg,Min,Sun,Max
        Book.objects.all().aggregate(Avg(price))

    5.2 annotate(*args,**kwargs)
        # 为查询集每一项生成聚合;
        # 查询每一个作者书的总价格;
        Book.objects.values("authors_name").annotate(Sum(price))

6.F/Q查询
    # 需求,对数据库中所有价格都加上共同值;
    models.Book.objects.all().update(price=price+20)????????不行!!!!
    6.1 F查询
        # 使用查询条件的值(数),专门取对象中某列值的操作;
        # F(price) 将字段的值取出来;
        from django.db.models import F
        models.Book.objects.all().update(price=F(price)+20)
    
    6.2 Q查询(封装关键字查询)
        # 构建搜索条件
        from django.db.models import Q
        # 实现或‘|‘,且‘&‘,非‘~‘的条件查询;
        models.Book.objects.filter(Q(id=3)|Q(title=php))[0]
        # 实现多条件组合查询;
        models.Book.objects.filter( Q(price__gt=50) & ( Q(id=3)|Q(title=php) ) )
        # Q对象与关键字参数查询一起使用,Q对象放在前面;
        models.Book.objects.filter( Q(price__gt=50) & (Q(id=3)|Q(title=php)),title__startswith=p)

 

以上是关于ORM增删改查(关联 | 聚合 | F/Q)&惰性机制 | Django开发的主要内容,如果未能解决你的问题,请参考以下文章

Python学习第130天(Django中ORM一对多的增删改查)

Beego脱坑(十三)ORM基本增删改查

beego 初体验 - orm - 增删改查

orm的增删改查

Hibernate ORM框架——续第一章:Java增删改查与Hibernate的增删改查的对比

ORM简单增删改查