Django学习手册 - ORM 数据创建/表操作 汇总

 ORM 查询的数据类型:

  QuerySet与惰性机制(可以看作是一个列表)

  所谓惰性机制:表名.objects.all()或者.filter()等都只是返回了一个QuerySet(查询结果集对象),它并不会马上执行sql,而是当调用QuerySet的时候才执行

  

QuerySet特点:

       <1>  可迭代的 

       <2>  可切片

       <3>  惰性计算和缓存机制

  例:

info=models.table_name.objects.all()[0:5]  #切片
info= models.table_name.objects.all()[3]    #索引

info= models.table_name.objects.all()        #可迭代
print(info.title)
for obj in info:                     
    print(obj.title)
 

 

 类对象

  类对象
  获取字段数值为  类.字段名 

 

 

创建 models 数据库

  一对一表创建

class A1(models.Model):
    id = models.IntegerField(primary_key=True)
    A11 = models.CharField(max_length=20)
    A12 = models.CharField(max_length=20)
    A13 = models.CharField(max_length=20)

class E1(models.Model):
    id = models.IntegerField(primary_key=True)
    E11 = models.OneToOneField('A1',to_field='id',on_delete=models.CASCADE)
    E12 = models.CharField(max_length=20)

# 定义 一对一关联:
# 格式:
# 字段 = models.OneToOneFied('关联表',to_field='关联表字段',on_delete=models.CASCADE)
    # 可添加参数:
    # related_name=名字  #外键反向查找别名(方便反向查找)
        # 使用方式; obj.名字.all()
        #在写ForeignKey字段的时候,如果想要在反向查找时不使用默认的 小写的表名_set,就在定义这个字段的时间加related参数!
    # related_query_name 字段=别名
        # 使用方式; obj.别名.all()
        # 一张表内两个外键 需要添加 related_query_name= 名字 从而识别是哪个外键值
# 示例:
# B11 = models.ForeignKey('A1',to_field='id',on_delete=models.CASCADE)

 

  外键(一对多创建)

# B1表跟A1表形成外键关系
class A1(models.Model):
    id = models.IntegerField(primary_key=True)
    A11 = models.CharField(max_length=20)
    A12 = models.CharField(max_length=20)
    A13 = models.CharField(max_length=20)

class B1(models.Model):
    id = models.IntegerField(primary_key=True)
    B11 = models.ForeignKey('A1',to_field='id',on_delete=models.CASCADE)
    B12 = models.CharField(max_length=20)
    B13 = models.CharField(max_length=20)

# 定义 外键:
# 格式:
# 字段 = models.ForeignKey('关联表',to_field='关联表字段',on_delete=models.CASCADE)
    # 可添加参数:
    # related_name=名字  #外键反向查找别名(方便反向查找)
        # 使用方式; obj.名字.all()
        #在写ForeignKey字段的时候,如果想要在反向查找时不使用默认的 小写的表名_set,就在定义这个字段的时间加related参数!
    # related_query_name 字段=别名
        # 使用方式; obj.别名.all()
        # 一张表内两个外键 需要添加 related_query_name= 名字 从而识别是哪个外键值
# 示例:
# B11 = models.ForeignKey('A1',to_field='id',on_delete=models.CASCADE)

 

  多对多表创建

# C1表跟D1表形成多对多的关系
class C1 (models.Model):
    id = models.IntegerField(primary_key=True)
    m = models.ManyToManyField('D1')
    C12 = models.CharField(max_length=20)
    C13 = models.CharField(max_length=20)

class D1 (models.Model):
    id = models.IntegerField(primary_key=True)
    D12 = models.CharField(max_length=20)
    D13 = models.CharField(max_length=20)

# 定义 多对多:
# 格式:
# 字段 = models.ForeignKey('关联表',to_field='关联表字段',on_delete=models.CASCADE)
    # 可添加参数:
    # through='UserFans'指定第3张关系表的表名
    # through_fields    指定第3张关系表的字段
# 示例:
# m = models.ManyToManyField('D1')

 

 多对多自关联创建

# userinfo 形成多对多的自关联
class Userinfo(models.Model):
    nikename=models.CharField(max_length=32)
    username=models.CharField(max_length=32)
    password=models.CharField(max_length=64)
    sex=((1,''),(2,''))
    gender=models.IntegerField(choices=sex)
    m=models.ManyToManyField('Userinfo')

 

ORM 操作

  单表操作/追加参数

# # 单表添加数据
# 单表操作
    # 格式:
    # 表名.objects.create()  # 导入的是表
    # module.表名.objects.create()  # 导入的是module模块
    #
    # 添加方式一:
    # models.表名.objects.create(字段1='参数1', 字段2='参数2')
    #
    # 添加方式二:
    # obj = models.表名(字段1 = '参数1', 字段2 = '参数2')
    # obj.save()

    # 示例:
    # # 方式一
    # models.A1.objects.create(A11='A1',A12='1',A13='1')
    #
    # # 方式二
    # data = {'A11': 'A2', 'A12': '2', 'A13': '2'}
    # models.A1.objects.create(**data)
    #
    # # 方式三
    # data2 = {'A11': 'A3', 'A12': '3', 'A13': '3'}
    # obj = models.A1(**data2)
    # obj.save()

# QuerySet 数据类型:可以看作是一个列表
#   QuerySet 对象,可切片,索引,迭代

# 类对象: 就是一个类
#   相当于一个类,获取字段数值为 类.字段名

# 单表查询数据
    # 查询所有数据
    # 格式:
    #     info=models.表名.objects.all()
    # 返回值:
    # query_set对象集合 [对象1、对象2、.... ]

    # obj = models.A1.objects.all()
    # print(obj) # QuerySet 对象

    # 查询单条数据
    #方式一 filter
    # 格式一:
    # info = models.表名.objects.filter(字段=参数)
    # 返回值:
    # 取值可以为  info[0]
    # query_set对象集合 [对象1]
    # obj2 = models.A1.objects.filter(id=1)  #查询不到数据为 空 QuerySet对象
    # print(obj2) # QuerySet 对象

        # # filter 可追加参数
        # obj21 = models.A1.objects.filter(id=1).first()  #第一条
        # obj22 = models.A1.objects.filter(id=1).last()   #最后一条
        # obj23 = models.A1.objects.filter(id=1).values_list()   #元组类型输出
        # obj24 = models.A1.objects.filter(id=1).values()        #字典类型输出
        # # print(type(obj21/22/23/24))  #类对象

        # .oder_by(-id):按照某列排序
        # .exclude(字段):字段获取数据时排除

    #方式二 get
    # info = models.表名.objects.get(字段=参数)
    # 返回值:
    # 单个对象,没有找到会报错

    # obj3 = models.A1.objects.get(id=1)  #查询不到数据报错!!!!
    # print(obj3)
    # print(type(obj3))  #类对象

# 单表删除数据
    # 方式一:
    # models.A1.objects.filter(id=1).delete()

    # 方式二:
    # ob1 = models.A1.objects.get(id=1)
    # ob1.delete()
    # ob1.save()

# 单表修改数据
    #修改方式1 update()
    # 格式:
    # models.表名.objects.filter(字段=参数).update(字段=参数)
    # models.A1.objects.filter(id=3).update(A11='A33',A12='A33',A13='A33')

    # data_updata = {'A11':'A33','A12':'A33','A13':'A33'}
    # models.A1.objects.filter(id=4).update(**data_updata)

    #修改方式2 obj.save()
    # obj = models.表名.objects.filter(字段=参数).get(字段=参数)
    # obj.字段 = 参数
    # obj.save()

    # ob1 = models.A1.objects.get(id=3)
    # ob1.A11 = 'A44'
    # ob1.A12 = 'A44'
    # ob1.A13 = 'A44'
    # ob1.save()

    # 更新数据操作:
    # 示例:
    # 格式:
    #  models.表名.objects.update_or_create(条件1=参数1, defaults={字段:属性})

    # 示例:
    #  tk = username
    #    models.Token.objects.update_or_create(user=user, defaults={'token': tk})
    # 找到更新 如果没有找到创建defaults={} 中的数据

 

  一对一表查询

# 一对一表操作
    # 添加删除修改(略)
    # # 查询
    # 正向查询(根据ontoon字段直接查询)
    # info1 = models.E1.objects.filter(id=1).values('id','E12','E11__A12','E11__A13')
    # info2 = models.E1.objects.filter(id=1).first().E11
    # print(info1)  # QuerySet
    # print(info2)  # A1 object (3)

    # #反向查询(反向查询跟foreignkey不同时的不需要 表名_set 这里只需要对表表名即可)
    # info1 = models.A1.objects.filter(id=3).values('id','A12','e1__id','e1__E12')
    # info2 = models.A1.objects.filter(id=3).first().e1
    # print(info1)    # QuerySet
    # print(info2)    # E1 object (1)

 

  一对多表操作

# 一对多表操作(外键)
    # # 一对多表操作:
    # 添加方式一:
    # models.表名.objects.create(字段1='参数1',字段2='参数2',外键ID='参数')
    #
    # 添加方式二:
    # obj=models.表名(字段1='参数1',字段2='参数2',外键=参数)
    # obj.save()

    # 一对多添加数据
    #方式一
    # data = {'B12':'B66','B13':'B66','B11_id':3}
    # models.B1.objects.create(**data)

    #方式二
    # data = {'B12':'B55','B13':'B55','B11_id':4}
    # obj = models.B1(**data)
    # obj.save()


    # 一对多表删除数据(跟单表操作一样)
    # 方式一:
    # models.B1.objects.filter(id=6).delete()

    # 方式二:
    # models.B1.objects.get(B12='B66').delete()


    # 一对多表修改数据(跟单表操作一样)
    # models.B1.objects.filter(id=3).update(B11_id=4)


    #一对多表查询数据(跨表查询)
    # 一对多表 跨表查询(正向查找 B表-外键字段-A表字段,下面两句等效)
    # info = models.B1.objects.filter(id=3).first().B11
    # info2 = models.B1.objects.get(id=3).B11
    # print(info)     # A1 object (4)
    # print(info2)    # A1 object (4)

    # # 一对多表 跨表查询(反向查找)(下面两条结果一致)
    # #方式一(根据 类的方式查找 ) (info.小写表名_set)
    # info = models.A1.objects.filter(id=4)
    # info1 = info.first().b1_set.values()
    # print(info1)    #values --- QuerySet类型
    # #方式二(根据values方式查找)(在values中  '小写表名__字段名' )
    # info2 = models.A1.objects.values('b1__B11','b1__B12','b1__B13').filter(id=4)
    # print(info2)    #values --- QuerySet类型

 

  多对多表操作

    #多对多表操作
    #多对多表添加操作
    # 如果两表之间存在双向1对N关系,就无法使用外键来描述其关系了;
    # 只能使用多对多的方式,新增第三张表关系描述表;
    # add()   添加
    # clear() 清空
    # remove() 删除某个对象

    # 正向添加 通过 多对多字段m.add增加
    #C1表id =1 字段 关联 D1表的 id = 1,2,3
    # obj = models.C1.objects.filter(id=1).first()
    # obj.m.add(1,2,3)

    # 反向添加 通过 小写表名_set.add增加
    # D1表id =1 字段 关联 C1表的 id = 1,2,3
    # obj2 = models.D1.objects.filter(id=1).first()
    # obj2.c1_set.add(1,2,3)

    #C1 id=3 关联 D1表id>3的数据
    # obj1 = models.C1.objects.filter(id=3).first()
    # obj2 = models.D1.objects.filter(id__gt=3)
    # obj1.m.add(*obj2)


    #多对多表删除操作
    # 正向删除
    # obj1 = models.C1.objects.filter(id=1).first()
    # obj1.m.remove(1,2,3)

    # 逆向删除
    # obj2 = models.D1.objects.filter(id=1).first()
    # obj2.c1_set.remove(2,3)

    # 清除数据
    # obj3 = models.C1.objects.filter(id=3).first()
    # obj3.m.clear()

    #多对多修改
    # ManyToManyField()字段 自动创建第3张关系表,可以使用字段跨表查询,但无法直接操作第3张表,
    # obj.m.all() 只有查询和清空 方法

    #多对多查询
    # 正向查询(通过多对多字段 直接查询)
    # obj = models.C1.objects.get(id=3).m.values()
    # print(obj)

    # 反向查询(通过.表名_set 查询)
    # obj = models.D1.objects.get(id=1).c1_set.values_list()
    # print(obj)

  

  多对多自关联操作

# 多对多自关联(由原来的3张表,变成只有2张表)
# 把两张表通过 choices字段合并为一张表
# ‘第三张关系表’ 使用models.ManyToManyField('Userinfo')生成

    # 同表正反向查询
    # 多对多 自关联 通过男士查询女生
    # boy_obj = models.Userinfo.objects.filter(id=2).first()
    # res = boy_obj.m.all()
    # for row in res:
    #     print(row.nikename)

    # # 多对多自关联 之通过女士查询男生
    # girl_obj = models.Userinfo.objects.filter(id=4).first()
    # res = girl_obj.userinfo_set.all()
    # for obj in res:
    #     print(obj.nikename)

 

  查询性能探究

    # 查询性能 :
    # 1、select_related:结果为对象  注意query_set类型的对象 都有该方法
    # 原理: 查询时主动完成连表形成一张大表,for循环时不用额外发请求;
    # 试用场景: 节省硬盘空间,数据量少时候适用相当于做了一次数据库查询;
    # info = models.B1.objects.filter(B11=4).all().select_related()
    # for i in info:
    #     print(i)

    # 2、prefetch_related:结果都对象是
    # 原理:虽好,但是做连表操作依然会影响查询性能,所以出现prefetch_related
    # prefetch_related:不做连表,多次单表查询外键表 去重之后显示, 2次单表查询(有几个外键做几次1+N次单表查询,
    # 适用场景:效率高,数据量大的时候试用
    # info = models.B1.objects.filter(B11=4).all().prefetch_related()
    # for i in info:
    #     print(i)

 

  F查询与Q查询

# F查询与Q查询
    #F 可以获取对象中的字段的属性(列),并对其进行操作;
    # from django.db.models import F,Q
    # models.表名.objects.all().update(price=F('price')+1)   #所在的列进行操作

    # Q多条件组合查询
    # Q()可以使orm的fifter()方法支持, 多个查询条件,使用逻辑关系(&、|、~)包含、组合到一起进行多条件查询;
    # 语法:
    # fifter(Q(查询条件1)| Q(查询条件2))
    # fifter(Q(查询条件2)& Q(查询条件3))
    # fifter(Q(查询条件4)& ~Q(查询条件5))
    # fifter(Q(查询条件6)| Q(Q(查询条件4)& ~ Q(Q(查询条件5)& Q(查询条件3)))包含

        # from django.db.models import F,Q
        #     1、F 可以获取对象中的字段的属性(列),并且对其进行操作;
        #     # models.Book.objects.all().update(price=F('price')+1)
        #     2、Q多条件组合查询
        #     #如果 多个查询条件 涉及到逻辑使用 fifter(,隔开)可以表示与,但没法表示或非得关系
        #     #查询 书名包含作者名的书
        #     book=models.Book.objects.filter(title__icontains='伟',author__name__contains='伟').values('title')
        #     #如何让orm 中得 fifter 支持逻辑判断+多条件查询? Q()登场
        #     book=models.Book.objects.filter(Q(title__icontains='伟') & Q(author__name__contains='伟')).values('title')
        #     book=models.Book.objects.filter(Q(author__name__contains='伟') & ~Q(title__icontains='伟')).values('title')
        #
        #    #多条件包含组合查询
        #    #查询作者姓名中包含 方/少/伟/书名包含伟3字 并且出版社地址以山西开头的书
        #     book=models.Book.objects.filter(
        #                                     Q(
        #                                     Q(author__name__contains='方') |
        #                                     Q(author__name__contains='少') |
        #                                     Q(title__icontains='伟')|
        #                                     Q(author__name__contains='伟')
        #                                     )
        #                                     &
        #                                     Q(publish__addr__contains='山西')
        #                                     ).values('title')
        #     print(book)

        # 注意:Q查询条件和非Q查询条件混合使用注意,不包Q()的查询条件一点要放在Q(查询条件)后面

 

部分资料查询于
https://www.cnblogs.com/sss4/p/7070942.html

 

转载于:https://www.cnblogs.com/Anec/p/9981899.html

你可能感兴趣的:(python,数据库)