zoukankan      html  css  js  c++  java
  • Django ORM框架之CRUD操作

    前言:上篇文章中简单记录了Django通过ORM框架中的对象与数据库中的对象映射,即如何创建模型类、定义类属性、生成迁移脚本、执行迁移脚本生成数据表等操作。本篇文章会继续记录Django通过ORM框架操作数据库中的数据,即生成数据表之后对表中数据的操作:CRUD(创建、读取(查询)、更新、删除)。

    一、创建数据(C)

    1、创建主表数据(无外键字段)

    方式一:1)实例化模型类,根据字段定义规则传递关键字参数;

        2)调用模型对象的save()方法

    注意:此种方式必须要调用save方法,才会执行sql语句,将数据写入到表中

    示例:在调试模式下运行,查看代码执行过程

    PS:此处需要添加监听器,监测否有sql语句执行,那么如何添加该监听器呢?

    1)导入django.db中的connection

    2)调试模式下,在Variables中添加监听器,输入connection.queries

    运行代码可见:创建模型对象project_obj后,并未监测到sql语句执行

    查看tb_projects数据表中也无数据生成

    执行save方法后,监听到sql语句执行,查看数据表中有数据生成

     

    方式二:模型类名.objects.create(关键字参数)

    注意:1)此种方式无需调用save方法,因为在create方法源码里实现了实例化模型类和调用save方法,并将模型对象返回

         2)模型类名.objects 返回的是Manage对象,是一个管理器对象

    示例:

    2、创建从表数据(有外键字段,需要解决从表外键对应的主表数据如何传值)

    方式一:1)获取主表模型对象

        2)从表模型类名.objects.create(关键字参数, 外键名=主表模型对象)

    示例:

    方式二:1)获取主表模型对象的id属性值

        2)从表模型类名.objects.create(关键字参数, 外键名_id=主表模型对象的id属性值)

    示例:

    二、读取数据(R)

    1、读取多条数据

    1)读取数据表中的所有数据:模型类名.objects.all()

    示例:

    注意:a)模型类名.objects.all() 返回的是 QuerySet 对象,QuerySet 对象中包裹着多个模型对象

       b)QuerySet 对象类似list,支持正值索引取值、正值切片操作、len()方法求长度、还支持迭代(可以使用for循环对查询集进行迭代),可以使用list(QuerySet对象)将去转换为list

         c)QuerySet 对象具有惰性查询的特性,即在真正'用'数据时,才会执行sql语句

         d)QuerySet 对象具有链式调用特性,即filter方法可以继续调用filter方法(或all方法)

       e)QuerySet 对象常用方法:

        first()  获取查询集中第一条数据(即模型对象)

        last()  获取查询集中最后一天数据(即模型对象)

        count()  获取查询集中有多少条数据(即模型对象的个数)

        exists()  判断查询集是否为空

    2)读取符合条件的数据(条件查询):模型类名.objects.filter(查询条件)  或   模型类名.objects.exclude(查询条件)

    ** 查询条件格式:字段名__查询类型=具体值

    ** filter方法和exclude方法支持多种查询类型:

     a)等于:    字段名__exact=具体值  或 字段名=具体值

     b)大于:    字段名__gt=具体值

     c)大于等于:  字段名__gte=具体值

     d)小于:    字段名__lt=具体值

     e)小于等于:  字段名__lte=具体值

     f)包含:     字段名__contains=具体值,不忽略大小写;字段名__icontains=具体值,忽略大小写

     g)以...开头:   字段名__startswith=具体值,不忽略大小写;字段名__istartswith=具体值,忽略大小写

     h)以...结尾:   字段名__endswith=具体值,不忽略大小写;字段名__iendswith=具体值,忽略大小写

     i)是否为空:   字段名__isnull

    ** filter方法与exclude方法的区别:filter方法筛选出符合条件的数据并返回;exclude方法筛选出符合条件的数据后,取补集返回。

    示例:

    Projects.objects.filter(id__gt=1) --> 查询id>1的数据

    Projects.objects.exclude(id__gt=1) --> 查询id不大于1的数据 (即id<=1的数据)

    2、读取单条数据

    方式一:模型类名.objects.get(查询条件)

    示例:

    注意:1)如果条件无法查询出结果(即没有符合条件的数据)时,此种方式会抛出异常

       2)如果条件查询出来的结果为多条时,此种方式也会抛出异常

         3)使用此种方式查询时,最好使用具有唯一约束的条件去查询

       4)get方法查询返回的结果是模型对象

       5)一般使用get方法查询时,会使用try...catch捕获异常

    方式二:模型类名.objects.filter(查询条件)

    示例:

     

    注意:1)使用filter方法查询时,如果符合查询条件的数据不存在,则返回空的QuerySet对象

       2)如果符合查询条件的数据为多条,则将这些数据(模型对象)包裹到QuerySet对象中返回

    另:在ORM框架中,会自动给每个模型类的逐渐添加一个别名pk,即使用主键查询时,可以使用pk__查询类型=具体值

    3、通过从表数据获取主表数据(实际上是通过从表外键字段来获取)

    1)获取从表模型对象

    2)从表模型对象.外键字段名

    示例:在接口表中查询id为1的接口的所属项目信息

    注意:虽然从表中外键字段值村粗的是主表模型对象的id,但通过“从表模型对象.外键字段名”获取的是主表模型对象 

    4、通过主表数据获取从表数据

    1)获取主表模型对象

    2)主表模型对象.从表模型类名小写_set.查询方法(get/filter/exclude/all)

    示例:查询name为‘测试项目’的项目所包含的所有接口信息

    注意:1)从表模型类名小写_set 是ORM框架提供给主表模型对象的默认属性主表模型对象.从表模型类名小写_set 返回的是从表的manage对象

       2)从表模型类名小写_set 可以修改,在定义外键字段时,可以指定related_name属性的值,related_name代表的是主表获取从表数据的引用名称

       3)不属于多表查询(执行了多条查询语句)

    5、多表查询(关联查询)

    1)通过主表参数来获取从表数据:要获取的是从表的数据,所以在从表查询,查询条件为主表字段的限制条件

      即:从表模型类名.objects.filter(外键名__主表字段名__查询类型=具体值)

    示例:查询leader为‘ppd’的项目的所有接口信息

     

    注意:1)外键名__ 相当于是获取主表的引用,projects__name相当于是在使用主表的name字段做过滤

       2)多表关联:外键1__外键2__外键3__xx字段__查询类型=具体值

    2)通过从表参数来获取主表数据:要获取的是主表数据,所以在主表查询,查询条件为从表字段的限制条件

       即:主表模型类名.objects.filter(从表模型类名小写__从表字段名__查询类型=具体值)

    示例:查询接口名称中包含‘登录’的所有项目信息

    6、查询条件间的逻辑关系

    1)'与' 关系

    方式一:在同一个filter方法内部,添加多个关键字参数(查询条件),这些参数之间为'与'关系

    示例:查询name中包含'2',且leader也包含'2'的项目信息

    方式二:多次调用filter方法,多个filter方法的查询条件间为'与'关系

    示例:

    方式三:通过Q查询实现,即 模型类名.objects.filter(Q(字段名__查询类型=具体值) & Q(字段名__查询类型=具体值))

    2)'或' 关系

    通过Q查询实现:1)导入Q类,from django.db.models import Q

             2)实例化Q对象,参数为查询条件,多个Q对象之间使用 | ,那么这些Q对象之间为'或'关系

    即:模型类名.objects.filter(Q(字段名__查询类型=具体值) | Q(字段名__查询类型=具体值))

    示例:查询name包含'2' 或 leader是'yxj'的项目信息

    7、对查询结果排序

    通过QuerySet对象(或manager对象)提供的order_by方法实现排序,默认按照指定的字段升序排序,如果字段名前加“-”,则表示降序排序

    即:QuerySet对象(或manager对象).order_by('字段名1', '字段名2', ... )

    示例:查询name包含'2'的项目信息,并通过name进行降序排序,再通过leader进行升序排序

     

    三、更新数据(U)

    1、更新一条数据:

    方式一:通过给模型对象属性赋新值 实现数据更新

      1)获取要更新数据的模型对象:模型类名.objects.get(查询条件)

      2)给要修改的模型对象属性赋值:模型对象.属性 = 新值

      3)调用模型对象的save方法:模型对象.save()

    示例:

    更新id为1的项目的name和leader信息

    注意:1)从上图可看出,调用save方法执行的sql语句为完整更新,即 虽然我只给name和leader赋新值,但执行save方法后,该条数据的所有字段值都进行了更新

       2)使用此种方式更新数据时,往往需要给save方法传递update_fields参数(序列类型),指定需要更新的字段名称

    方式二:调用查询集对象的update方法实现

        即:模型类名.objects.filter(具有唯一约束的字段条件).update(字段名='新值')

    2、更新多条数据 :通过调用查询集对象的update方法实现数据更新

       即:模型类名.objects.filter(查询条件).update(字段名1='新值1', 字段名2='新值2', ... )

    示例:更新name含有'22'的项目的leader为'小潘达'

    注意:1)update方法返回的是更新成功的数据条数

       2)通过给模型对象属性赋值的方式更新数据,需要手动的调用save方法后才会执行sql语句,将更新的数据写入数据表,而update方法不需要调用save方法

    四、删除数据(D)

    1、删除一条数据:通过调用模型对象的delete方法实现数据删除

      1)获取要删除的数据的模型对象:模型类名.objects.get(查询条件)

      2)调用模型对象的delete方法:模型对象.delete()

    示例:删除id为6的项目数据

    2、删除多条数据:通过调用QuerySet对象的delete方法实现多条数据的删除

      1)获取要删除的数据查询集对象:模型类名.objects.filter(查询条件)

      2)调用查询集对象的delete方法:查询集对象.delete()

    示例:删除name包含'yxj'的项目数据

    总结:本篇文章记录了Django ORM框架对数据进行增删改查操作,重点和难点都在查询数据上,单表查询、多表查询都需要多多练习才能掌握其中的知识点!

    本博客仅为本人学习过程中的记录,欢迎一起交流经验。
  • 相关阅读:
    .NET正则基础之——平衡组
    正则基础之——贪婪与非贪婪模式
    正则应用之——日期正则表达式
    文件指针/句柄(FILE*)、文件描述符(fd)以及 文件路径(filepath)的相互转换(完整版,收集,整理)
    linux c 发送邮件
    select, poll和epoll的区别(转)
    linux c 中文支持
    修改远程桌面连接端口(PortNumber)
    libhdfs编译,安装,配置,使用
    C语言字节对齐详解
  • 原文地址:https://www.cnblogs.com/panpanda/p/15169852.html
Copyright © 2011-2022 走看看