Django學習手冊 - ORM 數據建立/表操做 彙總

 ORM 查詢的數據類型:

  QuerySet與惰性機制(能夠看做是一個列表)

  所謂惰性機制:表名.objects.all()或者.filter()等都只是返回了一個QuerySet(查詢結果集對象),它並不會立刻執行sql,而是當調用QuerySet的時候才執行html

  

QuerySet特色:sql

       <1>  可迭代的 數據庫

       <2>  可切片django

       <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) 

 

 類對象

  <class 'models.表名'>類對象
  獲取字段數值爲  類.字段名 fetch

 

 

建立 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 對象,可切片,索引,迭代

# <class 'models.A1'>類對象: 就是一個類 # 至關於一個類,獲取字段數值爲 類.字段名

# 單表查詢數據
    # 查詢全部數據
    # 格式:
    # info=models.表名.objects.all()
    # 返回值:
    # query_set對象集合 [對象一、對象二、.... ]

    # 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)) #<class 'models.A1'>類對象

        # .oder_by(-id):按照某列排序
        # .exclude(字段):字段獲取數據時排除

    #方式二 get
    # info = models.表名.objects.get(字段=參數)
    # 返回值:
    # 單個對象,沒有找到會報錯

    # obj3 = models.A1.objects.get(id=1) #查詢不到數據報錯!!!!
    # print(obj3)
    # print(type(obj3)) #<class 'models.A1'>類對象

# 單表刪除數據
    # 方式一:
    # 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)

 

  查詢性能探究

# 查詢性能 :
    # 一、select_related:結果爲對象 注意query_set類型的對象 都有該方法
    # 原理: 查詢時主動完成連表造成一張大表,for循環時不用額外發請求;
    # 試用場景: 節省硬盤空間,數據量少時候適用至關於作了一次數據庫查詢;
    # info = models.B1.objects.filter(B11=4).all().select_related()
    # for i in info:
    # print(i)

    # 二、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
        # 一、F 能夠獲取對象中的字段的屬性(列),而且對其進行操做;
        # # models.Book.objects.all().update(price=F('price')+1)
        # 二、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.htmlspa

相關文章
相關標籤/搜索