<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Django -ORM

      單表操作

      添加記錄

      1     方法一: 實例化Book類 進行添加記錄
      2 
      3     book_obj = Book(id=1,title='python',price=101,pub_date='2014-02-13',publish="華夏出版社")
      4     book_obj.save()    # 此方法添加之后必須有 save 操作 ,否則數(shù)據(jù)不會增加
      5 
      6     方法二: 使用Book的 object管理器的create方法添加記錄
      7     obj = Book.objects.create(title='C++',price=89,pub_date='2014-12-03',publish='海浪出版社')
      8     print(obj.title )
      
      

      查詢表記錄API

      (1). all()方法:查詢所有數(shù)據(jù)  返回一個Queryset對象

      (2).first() 和 last()方法: 返回第一個和最后一個對象 返回值:models對象 調(diào)用者: Queryset
      (3). filter(**kwargs):返回和篩選條件相匹配的對象 調(diào)用者:object管理器  返回值:Queryset對象
      (4).get(**kwargs)方法: 返回與所給篩選條件相匹配的model對象  調(diào)用者:object管理器  返回值:model對象
      (5). exclude(**kwargs)方法:排除符合條件的數(shù)據(jù)  調(diào)用者:Queryset對象  返回值:Queryset對象
      (6). order_by(**kwargs)方法:根據(jù)條件進行排序  調(diào)用者:Queryset對象  返回值:Queryset對象
      (7).count()方法:對數(shù)據(jù)計數(shù)(可加約束)  調(diào)用者:object管理器  返回值:int數(shù)值
      (8).exist()方法:判斷數(shù)據(jù)是否為空  調(diào)用者:Queryset對象  返回值:bool類型
      (9).value()方法:通過內(nèi)循環(huán)獲取對應(yīng)字段的數(shù)據(jù) 調(diào)用者:object管理器或者Queryset對象 返回值:Queryset對象(其中數(shù)據(jù)以字典的形式存儲)
      (10).value_list()方法:通過內(nèi)循環(huán)獲取對應(yīng)字段的數(shù)據(jù)  調(diào)用者:object管理器或者Queryset對象  返回值:Queryset對象(其中數(shù)據(jù)以元組的形式存儲)
      (11).distinct()方法:對于數(shù)據(jù)中的某一字段進行去重  調(diào)用者:Queryset對象  返回值:Queryset對象(其中數(shù)據(jù)以字典的形式存儲)
       1 obj = Book.objects.all()
       2 print(obj)   # 返回Queryset列表對象 :[obj1,obj2,obj3,....]
       3 print(type(obj))
       4 
       5  for i in obj:
       6      print(i.title)
       7 
       8 '''
       9 遍歷書名:
      10     python
      11     java
      12     lua
      13     lua
      14     lua
      15     C++
      16 '''
      17 print(obj[0].title,obj[1].title)   # python java
      all()方法:查詢所有數(shù)據(jù) 返回一個Queryset
       first_obj = Book.objects.all().first()
       last_obj = Book.objects.all().last()
       print(first_obj,last_obj)   # Book object (1) Book object (6)
      # 相當于
      first_obj = Book.objects.all()[0]
      print(first_obj)   # Book object (1)
      first() 和 last()方法: 返回第一個和最后一個對象 返回值:models對象 調(diào)用者: Queryset
       book_list = Book.objects.filter(publish='海龜出版社')
      print(book_list)   # <QuerySet [<Book: Book object (2)>, <Book: Book object (3)>, <Book: Book object (4)>, <Book: Book object (5)>]>
      fir_obj = Book.objects.filter(publish='海龜出版社').first()  # Book object (2)
      last_obj = Book.objects.filter(publish='海龜出版社').last()  # Book object (5)
      filter(**kwargs):返回和篩選條件相匹配的對象 調(diào)用者:object管理器 返回值:Queryset對象
      # 只有結(jié)果為一時才有效  查詢結(jié)果為空或者為多者時都會報錯
      
       obj = Book.objects.get(title='python')   # model對象 :Book object (1)
       print(obj.title)  # python
      # obj = Book.objects.get(title='lua')  # 查詢結(jié)果為多者報錯:get() returned more than one Book -- it returned 3!
      get(**kwargs)方法: 返回與所給篩選條件相匹配的model對象 調(diào)用者:object管理器 返回值:model對象
      book_list  = Book.objects.all().exclude(title='python')  # 單條件排除
      book_list=Book.objects.all().exclude(title='C++',publish="海浪出版社")  # 多條件排除
      # for book in  book_list:
      #     print(book.publish)
      exclude(**kwargs)方法:排除符合條件的數(shù)據(jù) 調(diào)用者:Queryset對象 返回值:Queryset對象
      obj = Book.objects.all().order_by("title")  # 單條件排序
      
      obj2 = Book.objects.all().order_by("title","price")  # 多條件排序
      order_by(**kwargs)方法:根據(jù)條件進行排序 調(diào)用者:Queryset對象 返回值:Queryset對象
      res = Book.objects.all().count()
      print(res,{"type":type(res)})      # 6 {'type': <class 'int'>}
      count()方法:對數(shù)據(jù)計數(shù)(可加約束) 調(diào)用者:object管理器 返回值:int數(shù)值
       ret  = Book.objects.all().exists()
      print(ret,{"type":type(ret)})       # True {'type': <class 'bool'>}
      exist()方法:判斷數(shù)據(jù)是否為空 調(diào)用者:Queryset對象 返回值:bool類型
       ret1 = Book.objects.all().values("title")    #  等于 ret1 = Book.objects.values("title")
      ret2 = Book.objects.all().values("title",'price')
      
      print(ret1,{"type":type(ret1)})
      # # <QuerySet [{'title': 'python'}, {'title': 'java'}, {'title': 'lua'}, {'title': 'Go'}, {'title': 'C#'}, {'title': 'C++'}]> {'type': <class 'django.db.models.query.QuerySet'>}
      print(ret2,{"type":type(ret2)})
      # <QuerySet [{'title': 'python', 'price': Decimal('101.00')}, {'title': 'java', 'price': Decimal('100.00')}, {'title': 'lua', 'price': Decimal('99.00')}, {'title': 'Go', 'price': Decimal('68.00')}, {'title': 'C#', 'price': Decimal('70.00')}, {'title': 'C++', 'price': Decimal('89.00')}]> {'type': <class 'django.db.models.query.QuerySet'>}
      value()方法:通過內(nèi)循環(huán)獲取對應(yīng)字段的數(shù)據(jù) 調(diào)用者:object管理器或者Queryset對象 返回值:Queryset對象(其中數(shù)據(jù)以字典的形式存儲)
       ret1 = Book.objects.all().values_list("title")
       # ret1 = Book.objects.values("title")  # 同上
      ret2 = Book.objects.all().values_list("title", 'price')
      #
      print(ret1, {"type": type(ret1)})
       # <QuerySet [('python',), ('java',), ('lua',), ('Go',), ('C#',), ('C++',)]> {'type': <class 'django.db.models.query.QuerySet'>}
      print(ret2, {"type": type(ret2)})
      # <QuerySet [('python', Decimal('101.00')), ('java', Decimal('100.00')), ('lua', Decimal('99.00')), ('Go', Decimal('68.00')), ('C#', Decimal('70.00')), ('C++', Decimal('89.00'))]> {'type': <class 'django.db.models.query.QuerySet'>}
      value_list()方法:通過內(nèi)循環(huán)獲取對應(yīng)字段的數(shù)據(jù) 調(diào)用者:object管理器或者Queryset對象 返回值:Queryset對象(其中數(shù)據(jù)以元組的形式存儲)
       ret = Book.objects.all()
       print(ret)
       ret1 = Book.objects.values('price')
       print(ret1)
       ret2 = Book.objects.values('price').distinct()
       print(ret2)
      '''
      結(jié)果:
      ret: <QuerySet [<Book: Book object (1)>, <Book: Book object (2)>, <Book: Book object (3)>, <Book: Book object (4)>, <Book: Book object (5)>, <Book: Book object (6)>]>
      
      ret1: <QuerySet [{'price': Decimal('100.00')}, {'price': Decimal('100.00')}, {'price': Decimal('99.00')}, {'price': Decimal('68.00')}, {'price': Decimal('70.00')}, {'price': Decimal('89.00')}]>
      
      ret2: <QuerySet [{'price': Decimal('100.00')}, {'price': Decimal('99.00')}, {'price': Decimal('68.00')}, {'price': Decimal('70.00')}, {'price': Decimal('89.00')}]>
      
      '''
      distinct()方法:對于數(shù)據(jù)中的某一字段進行去重 調(diào)用者:Queryset對象 返回值:Queryset對象(其中數(shù)據(jù)以字典的形式存儲)
       

      ========================= 單表查詢之模糊查詢 =========================
      數(shù)值方面模糊查詢

      (1). price__lt 查詢價格小于80的數(shù)據(jù)
       ret1 = Book.objects.filter(price__lt=80)
       print(ret1)    # <QuerySet [<Book: Book object (4)>, <Book: Book object (5)>]>
      (2). price__gt 查詢價格大于70的數(shù)據(jù)
       ret2 = Book.objects.filter(price__gt=70)
       print(ret2)   # <QuerySet [<Book: Book object (1)>, <Book: Book object (2)>, <Book: Book object (3)>, <Book: Book object (5)>, <Book: Book object (6)>]>
      (3).查詢價格大于70且價格小于80的數(shù)據(jù)
       ret3 = Book.objects.filter(price__gt=70,price__lt=80,)
       print(ret3)   # <QuerySet [<Book: Book object (5)>]>
      (4).查詢價格為列表中的數(shù)據(jù)
       ret4 = Book.objects.filter(price__in=[100,200])
       print(ret4)  # <QuerySet [<Book: Book object (1)>]>

      ======== 內(nèi)容方面模糊查詢

      ===包含方面查詢:
      (1).查詢title字段包含小寫字母”o“的數(shù)據(jù) 區(qū)分大小寫
       ret1 = Book.objects.filter(title__contains="o")
       print(ret1)  # <QuerySet [<Book: Book object (5)>, <Book: Book object (6)>]>
      # 查詢title字段包含小寫字母”O(jiān)“的數(shù)據(jù)
      ret2 = Book.objects.filter(title__contains="O")
      print(ret2)   # <QuerySet []>  # 沒有數(shù)據(jù)顯示為空

      (2).不區(qū)分大小寫查詢
       ret = Book.objects.filter(title__icontains="O")
       print(ret)  # <QuerySet []>

      ===開頭結(jié)尾查詢:

      1、查詢以”C“為開頭的數(shù)據(jù) 區(qū)分大小寫
       ret1 = Book.objects.filter(title__startswith='C')
       print(ret1)  # <QuerySet [<Book: Book object (5)>, <Book: Book object (6)>]>

      2、查詢以”c“為開頭的數(shù)據(jù) 區(qū)分大小寫
       ret1 = Book.objects.filter(title__startswith='c')
       print(ret1)   # <QuerySet []>

      3、查詢以”c“為開頭的數(shù)據(jù) 不區(qū)分大小寫
       ret1 = Book.objects.filter(title__istartswith='c')
       print(ret1)  # <QuerySet [<Book: Book object (5)>, <Book: Book object (6)>]>

      4、查詢以”n“為結(jié)尾的數(shù)據(jù) 區(qū)分大小寫
       ret1 = Book.objects.filter(title__endswith='n')
       print(ret1)  # <QuerySet [<Book: Book object (1)>]>

      5、查詢以”N“為結(jié)尾的數(shù)據(jù) 區(qū)分大小寫
       ret1 = Book.objects.filter(title__endswith='N') 
       print(ret1)  # <QuerySet []>

      6、查詢以”N“為結(jié)尾的數(shù)據(jù) 不區(qū)分大小寫
       ret1 = Book.objects.filter(title__iendswith='N')
       print(ret1)  # <QuerySet [<Book: Book object (1)>]>


      ========== 日期方面查詢

      1、 查詢年份為2014
      ret1 = Book.objects.filter(pub_date__year=2014,)
      print(ret1)  # <QuerySet [<Book: Book object (1)>, <Book: Book object (6)>]>
      2、 查詢年份為2014 月份為12
      ret2=Book.objects.filter(pub_date__year=2014,pub_date__month=12)
      print(ret2)   # <QuerySet [<Book: Book object (6)>]>
      3、 查詢年份為2014 月份為12 天數(shù)為3的數(shù)據(jù)
      ret3 = Book.objects.filter(pub_date__year=2014,pub_date__month=12,pub_date__day=3)
      print(ret3)   # <QuerySet [<Book: Book object (6)>]>

      刪除記錄和修改記錄

      1、 刪除:delete()方法   調(diào)用者:Queryset對象 和 model對象
       ret = Book.objects.filter(title="C++").delete()   # Queryset對象調(diào)用
       print(ret)   #  (1, {'app01.Book': 1})
      
       ret1 = Book.objects.filter(publish="海洋出版社").first().delete()   # Queryset對象調(diào)用
       print(ret1)   #  (1, {'app01.Book': 1})

      2、 修改記錄:update()方法 調(diào)用者: Queryset對象
      ret = Book.objects.filter(title="C#").update(price=99)# print(ret)   # 2

      多表操作

      數(shù)據(jù)庫關(guān)系:

      • 一對一
      • 一對多
      • 多對多

       

      一、創(chuàng)建模型

      實例:我們來假定下面這些概念,字段和關(guān)系
      作者模型:一個作者有姓名和年齡。
      作者詳細模型:把作者的詳情放到詳情表,包含生日,手機號,家庭住址等信息。作者詳情模型和作者模型之間是一對一的關(guān)系(one-to-one)
      出版商模型:出版商有名稱,所在城市以及email。
      書籍模型: 書籍有書名和出版日期,一本書可能會有多個作者,一個作者也可以寫多本書,所以作者和書籍的關(guān)系就是多對多的關(guān)聯(lián)關(guān)系(many-to-many);一本書只應(yīng)該由一個出版商出版,所以出版商和書籍是一對多關(guān)聯(lián)關(guān)系(one-to-many)。
      模型建立如下:

      class Publish(models.Model):
          '''
          出版社信息表
          '''
          nid = models.AutoField(primary_key=True)
          name = models.CharField(max_length=32)
          city = models.CharField(max_length=32)
          tel =  models.IntegerField()
          email = models.EmailField()
      
      
      class Book(models.Model):
          '''
          書籍表
          '''
          nid = models.AutoField(primary_key=True)
          title = models.CharField(max_length=32)
          price = models.DecimalField(decimal_places=2,max_digits=8)
          pub_date = models.DateField()
          # 與Publish表建立一對多的關(guān)系 外鍵建立在多的一方:ForeignKey(to="關(guān)系表",to_field="關(guān)聯(lián)字段",on_delete=models.CASCADE)
          publish = models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)
          # 與Author表建立多對多的關(guān)系 ManyToManyField(to="關(guān)系表",)
          authors = models.ManyToManyField(to="Author",)
      
      
      
      class AuthorDetail(models.Model):
          '''
          作者詳情表
          '''
          nid = models.AutoField(primary_key=True)
          name = models.CharField(max_length=32)
          email = models.EmailField(max_length=32)
          addr = models.CharField(max_length=32)
      
      class Author(models.Model):
          '''
          作者表
          '''
          nid = models.AutoField(primary_key=True)
          name = models.CharField(max_length=32)
          # 與作者詳情表為一對一關(guān)系  使用OneToOneField(to="關(guān)系表",to_field="關(guān)聯(lián)字段",on_delete=models.CASCADE)
          #  在django 2.0 以上版本 需要加上 on_delete=models.CASCADE
          #  不然會報錯 ”TypeError: __init__() missing 1 required positional argument: 'on_delete'“
          authordetail = models.OneToOneField(to="AuthorDetail",to_field="nid" ,on_delete=models.CASCADE)    #  在django 2.0 以上版本 需要加上 on_delete=models.CASCADE
      注意:
      在django 2.0 以上版本 需要加上 “ on_delete=models.CASCADE ”,
      不然會報錯 ”TypeError: __init__() missing 1 required positional argument: 'on_delete'
      
      

      執(zhí)行命令后生產(chǎn)表如下:

          

       

       

       其中表“app01_book_authors” 是ORM根據(jù)models中的關(guān)聯(lián)關(guān)系生成的,不是我們手動創(chuàng)建的 

          # 與Author表建立多對多的關(guān)系 ManyToManyField(to="關(guān)系表",)
          authors = models.ManyToManyField(to="Author",)

      注意事項:

      • 表的名稱myapp_modelName,是根據(jù) 模型中的元數(shù)據(jù)自動生成的,也可以覆寫為別的名稱  
      • id 字段是自動添加的
      • 對于外鍵字段,Django 會在字段名上添加"_id" 來創(chuàng)建數(shù)據(jù)庫中的列名
      • 這個例子中的CREATE TABLE SQL 語句使用PostgreSQL 語法格式,要注意的是Django 會根據(jù)settings 中指定的數(shù)據(jù)庫類型來使用相應(yīng)的SQL 語句。
      • 定義好模型之后,你需要告訴Django _使用_這些模型。你要做的就是修改配置文件中的INSTALL_APPSZ中設(shè)置,在其中添加models.py所在應(yīng)用的名稱。
      • 外鍵字段 ForeignKey 有一個 null=True 的設(shè)置(它允許外鍵接受空值 NULL),你可以賦給它空值 None

      一、添加記錄:

      (1)一對一添加

          # 添加出版社信息(單表)
          pub = Publish.objects.create(nid=1,name="人民出版社",city="北京",tel=1234456,email="12156@qq.com")
          pub = Publish.objects.create(name="海南出版社",city="海南",tel=1232316,email="2421356@qq.com")

      數(shù)據(jù)庫數(shù)據(jù):

          

      (2)一對多添加

      往書籍Book表中添加數(shù)據(jù),并關(guān)聯(lián)出版社Publish表

          #  方式一
          # book_obj = Book.objects.create(nid=2,title="java",price=480,pub_date="2018-05-06",publish_id=1)
          # print(book_obj.title)
          # print(book_obj.price)
          # print(book_obj.publish)
          # print(book_obj.publish.city)
          # print(book_obj.publish.email)
          # print(book_obj.publish.tel)
          # print(book_obj.publish.tel)
          # print(book_obj.publish_id)
      
          # 方式二
          # 先取出一個Publish對象pub_obj 然后讓publish=pub_obj  Django會根據(jù)book表里的publish關(guān)系獲取到對應(yīng)的出版社id 然后進行關(guān)聯(lián)
          # pub_obj = Publish.objects.filter(nid=1).first()
          # book_obj = Book.objects.create(title="lua",price=12312,pub_date="2011-02-16",publish=pub_obj)
          #
          # print(book_obj.publish)       # Publish object (1)
          # print(book_obj.publish.city)  # 北京
          # print(book_obj.publish.email) # 12156@qq.com
          # print(book_obj.publish.tel)   # 1234456
          # print(book_obj.publish_id)    # 1

       數(shù)據(jù)庫數(shù)據(jù):表app01_book

          

      (3)多對多添加

      現(xiàn)在往作者表:Author、作者詳情表AuthDetail中添加數(shù)據(jù),并進行關(guān)聯(lián)

          # 創(chuàng)建作者信息
          AuthorDetail.objects.create(email="123123@qq.com",addr="sdfasdf")
          AuthorDetail.objects.create(email="421233@qq.com",addr="gesdf")
          AuthorDetail.objects.create(email="23145@qq.com",addr="hainan")
          AuthorDetail.objects.create(email="34212@qq.com",addr="beijing")
      
          Author.objects.create(name="Tom",authordetail_id=1)
          Author.objects.create(name="Jane",authordetail_id=2)
          Author.objects.create(name="Tone",authordetail_id=3)
          Author.objects.create(name="Jin",authordetail_id=4)
      
          # 給python關(guān)聯(lián)作者
          book1 = Book.objects.get(title='python')
          book2 = Book.objects.get(title='java')
      
          book1.authors.add(1)
          book1.authors.add(2)
          # 上面兩步等同于
          # book1.authors.add(*[1,2])
      
          book2.authors.add(2,3)
      
          # 解決關(guān)聯(lián)信息
      
          book1.authors.remove(1)  # 單條解除
          book1.authors.clear()  # 全部解除
          print(book2.authors.all())  # <QuerySet [<Author: Tom>, <Author: Jin>]>

       

      表app01_author:

          

      表app01_authordetail :

           

      表app01_book_authors :

       

      二、查詢記錄:

      =========================基于對象的跨表查詢===========================

      正反向查詢:

          '''
          查詢分為正向和反向查詢 比如表A和表B 關(guān)聯(lián)屬性在A中
          
                    根據(jù)字段進行查詢:obj.關(guān)聯(lián)屬性
          正向查詢: A----------------------->B
                      
                      
                  根據(jù)表名進行查詢:obj.表名小寫_set.all()
          反向查詢: B------------------------>A
                    
          '''

       

      一對多查詢

          '''
          一對多:
          正向查詢: Book--------------->Publish
                      book_obj.publish
      
      
          反向查詢: Publish --------------->Book
                      pub_obj.book_set
          '''
          # 表Book和表Publish(一對多)  關(guān)聯(lián)屬性publish在Book中
          # 查詢書名python的出版社名字(正向查詢)
      
          book = Book.objects.filter(title='python').first()  # 獲取Book對應(yīng)的對象
          print(book.publish.name)  # 人民出版社
      
          # 查詢?nèi)嗣癯霭嫔绲某霭娴乃袝?反向查詢)
      
          pub_obj = Publish.objects.filter(name="人民出版社").first()  # 獲取Publish對應(yīng)的對象
          ret = pub_obj.book_set.all()    # 獲取對應(yīng)的書籍
          print(ret)   # <QuerySet [<Book: python>, <Book: java>, <Book: go>, <Book: lua>]>

       

      多對多查詢

          '''
          多對多:
          正向查詢: Book--------------->Author
                      book_obj.authors
      
          反向查詢: Author --------------->Book
                      author_obj.book_set.all()
          '''
          #  查詢書籍python的所有作者名字(正向查詢)
      
          book_obj = Book.objects.filter(title="python").first()
          ret = book_obj.authors.all()
          print(ret)   # <QuerySet [<Author: Tom>, <Author: Jane>]>
      
           # 查詢書籍Tom的所有書籍名字(反向查詢)
          author_obj = Author.objects.filter(name="Tom").first()
          ret =   author_obj.book_set.all()
          print(ret)   # <QuerySet [<Book: java>, <Book: python>]>

       

      一對一查詢

          '''
          一對一: 因為是一對一關(guān)系 所以查詢結(jié)果是唯一的  
          正向查詢: Author--------------->Authordetail
                      book_obj.authordetail
      
          反向查詢: Authordetail --------------->Author
                      authordetail_obj.author
          '''
          # 查詢Tom的地址
          author_obj = Author.objects.filter(name="Tom").first()
          print(author_obj.authordetail.addr)  # sdfasdf
      
          # 查詢郵箱為23145@qq.com的姓名和年齡
          authordetail_obj = AuthorDetail.objects.filter(email="23145@qq.com").first()
          print(authordetail_obj.author.name)   # Tone

       

      =========================基于雙下滑線的模糊查詢 ========================

      查詢方式:

      '''
      正向查詢用字段 反向查詢用 "表名小寫__屬性“ 從而告訴ORM引擎 join 哪張表
      '''
      一對多: 
      查詢書名為python的出版社名字
      '''
      sql語句查詢:
          select app01_publish.name from app01_book  inner join app01_publish  on
      app01_book.title="python" and app01_book.nid = app01_publish.nid;
      
      '''
      
      
      方式1 通過Book表join與其關(guān)聯(lián)的Publish表,屬于正向查詢;再按照字段 publish 告知ORM join Publish表
      ret1 = Book.objects.filter(title="python").values("publish__name")
      print(ret1)  # <QuerySet [{'publish__name': '人民出版社'}]>

      方式二:通過Publish表join與其關(guān)聯(lián)的Book表,屬于反向查詢;再按照表名小寫 book__title 告知ORM引擎 join Book表
      ret2 = Publish.objects.filter(book__title="python").values("name")
      print(ret2)  #  <QuerySet [{'name': '人民出版社'}]>

      兩種方式的sql語句:

          方式1 打印的sql語句:
          (0.001) SELECT "app01_publish"."name" FROM "app01_book" INNER JOIN "app01_publish" ON 
          ("app01_book"."publish_id" = "app01_publish"."nid") WHERE "app01_book"."title" = 'python' LIMIT 21; args=('python',)
          
          方式2 打印的sql語句:
          (0.000) SELECT "app01_publish"."name" FROM "app01_publish" INNER JOIN "app01_book" ON
           ("app01_publish"."nid" = "app01_book"."publish_id") WHERE "app01_book"."title" = 'python' LIMIT 21; args=('python',)

      從sql語句可以看出 ,兩種方式的sql語句都是一樣的  只不過順序顛倒了下

       多對多:

      現(xiàn)在用雙下劃線查詢上面的例子:

          #  查詢書籍python的所有作者名字(正向查詢)
          # 方式一:通過Book表join與其關(guān)聯(lián)的Author表 屬于正向查詢;再通過字段”authors“告知ORM join Author表
      
          ret = Book.objects.filter(title="python").values("authors__name")
          print(ret)   # <QuerySet [{'authors__name': 'Tom'}, {'authors__name': 'Jane'}]>
      
          # 方式二:通過Author表join與其關(guān)聯(lián)的Book表,屬于反向查詢;按表名小寫book告知ORM引擎join book_authors表
      
          ret = Author.objects.filter(book__title="python").values("name")
          print(ret) # <QuerySet [{'name': 'Tom'}, {'name': 'Jane'}]>

      一對一

          # 查詢Jane的addr
          # 方式一:通過Author表join與其關(guān)聯(lián)的Authordetail表 屬于正向查詢;再按照字段authordetail 告知ORM join Authordetail表表
          ret = Author.objects.filter(name="Jane").values("authordetail__addr")
          print(ret)  # <QuerySet [{'authordetail__addr': 'gesdf'}]>
      
          # 方式一:通過Authordetail表join與其關(guān)聯(lián)的Author表 屬于反向查詢;再按照表明小寫“author 告知ORM join Author表
          ret = AuthorDetail.objects.filter(author__name="Jane").values("addr")
          print(ret)  # <QuerySet [{'addr': 'gesdf'}]>

      連續(xù)跨表查詢

      查詢地址以“h”開頭的所有作者出版的 書籍以及出版社名稱

      方式一:

          '''
          拆分:以作者為根 查詢對應(yīng)的書籍名稱以及其出版社名稱
              查詢地址以“h”開頭的所有作者  
              出版的書籍以及出版社名稱
              
          涉及的表 :Author,AuthorDetail,Book,Publish
          Author與AuthorDetail有關(guān)聯(lián) 且屬于正向查詢 所以使用字段 authordetail 找出對應(yīng)的作者 --> Author.objects.filter(authordetail__addr__startswith="h")
          Author與Book有關(guān)聯(lián),且屬于反向查詢,所以使用小寫表名獲取書籍名稱 --> values("book__title")
          Author和Publish沒有關(guān)聯(lián),所以需要使用連續(xù)跨表查詢  values("book__publish__name")
          '''
          ret = Author.objects.filter(authordetail__addr__startswith="h").values("book__title","book__publish__name")
          print(ret)   # <QuerySet [{'book__title': 'java', 'book__publish__name': '人民出版社'}]>

      方式二:

          '''
          拆分:以書籍為根 查詢關(guān)系:Book --> Author --> AuthorDetail --> Publish
              查詢地址以“h”開頭的所有作者出版的書籍
              以及出版社名稱
          
          涉及的表 :Author,AuthorDetail,Book,Publish
          Book與AuthorDetail沒有關(guān)聯(lián) 所以需要使用連續(xù)跨表查詢 --> Book.objects.filter(authors__authordetail__addr__startswith="h")
          Book與Publish有關(guān)聯(lián),且屬于正向查詢 所以使用字段 publish 獲取出版社名字-> values('title',"publish__name")
          '''
        ret = Book.objects.filter(authors__authordetail__addr__startswith="h").values('title',"publish__name")
          print(ret)  # <QuerySet [{'title': 'java', 'publish__name': '人民出版社'}]>

      聚合查詢

      aggregate():聚合管理器, 需配合聚合函數(shù)使用 (Avg,Max,Min,Count,..)

      注意:aggregate() 返回的是一個字典 不再是Queryset集合

      示例:

          from django.db.models import Avg,Max,Min,Count  # 導(dǎo)入聚合函數(shù)
          ret = Book.objects.all().aggregate(Avg("price"))
          print(ret)   # {'price__avg': Decimal('3335.5')}  price__avg是ORM根據(jù)聚合函數(shù)和屬性以雙下劃線拼成的,也可以自定義鍵名
          ret = Book.objects.all().aggregate(avg_price=Avg("price"))
          print(ret)  # {'avg_price': Decimal('3335.5')}
      
          ret = Book.objects.all().aggregate(Max("price"),Min("price"),Count("price"))    # 獲取最高價格和最低價格 書籍數(shù)量
          print(ret)   # {'price__max': Decimal('12312'), 'price__min': Decimal('100'), 'price__count': 4}

       

      分組查詢

      單表分組查詢:

      先創(chuàng)建一個員工表:

      class Empers(models.Model):
          '''
          員工信息詳情表
          '''
          nid = models.AutoField(primary_key=True)
          department = models.CharField(max_length=32)
          name = models.CharField(max_length=32)
          email = models.EmailField(max_length=32)
          salary = models.IntegerField()
          provience = models.CharField(max_length=32)

      添加數(shù)據(jù):

          Empers.objects.create(name="join",email="sdsfs21@qq.com",salary="5333",department="開發(fā)部",provience="北京")
          Empers.objects.create(name="tom",email="52342s21@qq.com",salary="5377",department="開發(fā)部",provience="上海")
          Empers.objects.create(name="jane",email="21321@qq.com",salary="6000",department="銷售部",provience="天津")
          Empers.objects.create(name="愛爾蘭新",email="efas21@qq.com",salary="12000",department="后勤部",provience="北京")

      查詢示例:

          # 查詢所有部門及其員工的平均薪資
      
          ret = Empers.objects.values("department").annotate(Avg("salary"))
          print(ret) # <QuerySet [{'department': '后勤部', 'salary__avg': 12000.0}, {'department': '開發(fā)部', 'salary__avg': 5355.0}, {'department': '銷售部', 'salary__avg': 6000.0}]>
      
          # 查詢所有省份及其員工的人數(shù)
      
          ret = Empers.objects.values("provience").annotate(Count("name"))
          print(ret)  # <QuerySet [{'provience': '上海', 'name__count': 1}, {'provience': '北京', 'name__count': 2}, {'provience': '天津', 'name__count': 1}]>
      

      總結(jié):

       ORM語法:單表模型.objects.values("group by的字段").annotate(聚合函數(shù)(“字段”))

      單表模型.objects.values("group by的字段") 相當于 sql語句的:“select * from 表名 group by 字段”

      注意:

      在單表查詢中annotate是以前面的字段進行分組統(tǒng)計的,如果分組的字段包含主鍵,因為主鍵是唯一的,所以分組就是沒有意義的

       

      多表分組查詢:

      示例1:

          '''
          
          Book 表:
          nid title   pub_date    publish_id     price
          1    python    2018-05-06      1            100
          2    java    2018-05-06        1            480
          3    go        2018-08-26        1            450
          4    lua        2011-02-16      1            12312
      
          Publish 表:
          nid     name    city   tel              email
          1    人民出版社    北京        1234456        12156@qq.com
          14    海南出版社    海南        1232316        2421356@qq.com
          15    天津出版社    天津        2311312        34221356@qq.com
          
          # 查詢所有書籍及其出版社的名字
          sql語句查詢:
              select Book.title,Publish.name from Book inner join Publish on
               Book.publish_id = Publish.nid
      
          # 查詢每個出版社的名字及其出版書籍的個數(shù)
          sql語句查詢:
              先join兩張表:
              select * from app01_book inner join app01_publish on app01_book.publish_id = app01_publish.nid
              
             nid  title   pub_date    publish_id     price   nid     name    city   tel      email      
              1    python    2018-05-06    1               100      1    人民出版社    北京    1234456    12156@qq.com
              2    java    2018-05-06    14               480        14    海南出版社    海南    1232316    2421356@qq.com
              3    go        2018-08-26    1               450        1    人民出版社    北京    1234456    12156@qq.com
              4    lua        2011-02-16    1              12312        1    人民出版社    北京    1234456    12156@qq.com
              分組查詢sql語句:
                  select app01_publish.name,Count("title") from app01_book inner join app01_publish on 
                      app01_book.publish_id = app01_publish.nid group by app01_publish.nid
                   結(jié)果:   
                   id     name     Count("title") 
                    1  人民出版社        3
                    2  海南出版社        1              
          
          '''

      現(xiàn)在使用ORM語句進行查詢:

          # 方式一:通過主鍵進行分組 然后再獲取想要的字段
          # ret = Publish.objects.values("nid").annotate(c=Count("book__title"))
          # print(ret)  # <QuerySet [{'nid': 1, 'c': 3}, {'nid': 14, 'c': 1}, {'nid': 15, 'c': 0}]>
      
          ret = Publish.objects.values("nid").annotate(c=Count("book__title")).values("name","c")
          print(ret)  # <QuerySet [{'name': '人民出版社', 'c': 3}, {'name': '海南出版社', 'c': 1}, {'name': '天津出版社', 'c': 0}]>
      
          # 方式二:直接根據(jù)需分組的字段進行分組
          ret = Publish.objects.values("name").annotate(c=Count("book__title"))
          print(ret)  # <QuerySet [{'name': '人民出版社', 'c': 3}, {'name': '天津出版社', 'c': 0}, {'name': '海南出版社', 'c': 1}]>

      示例二:查詢每一個作者的名字以及出版過的書籍的最高價格

          '''
          sql語句查詢:
              select name,Max("app01_book".price) from app01_author inner join app01_authordetail on  
              app01_author.authordetail_id = app01_authordetail.nid inner join app01_book on 
              app01_author.nid = app01_book.nid group by app01_author.name
          '''
          ret = Author.objects.values("pk").annotate(max_price=Max("book__price")).values("name","max_price")
          print(ret) # <QuerySet [{'name': 'Tom', 'max_price': Decimal('480')}, {'name': 'Jane', 'max_price': Decimal('480')}, {'name': 'Tone', 'max_price': Decimal('480')}, {'name': 'Jin', 'max_price': Decimal('480')}]>
      
          # 等同于下面語句  
          ret = Author.objects.all().annotate(max_price=Max("book__price")).values("name","max_price")
          print(ret) # <QuerySet [{'name': 'Tom', 'max_price': Decimal('480')}, {'name': 'Jane', 'max_price': Decimal('480')}, {'name': 'Tone', 'max_price': Decimal('480')}, {'name': 'Jin', 'max_price': Decimal('480')}]>
      
          ret = Author.objects.annotate(max_price=Max("book__price")).values("name","max_price")
          print(ret) # <QuerySet [{'name': 'Tom', 'max_price': Decimal('480')}, {'name': 'Jane', 'max_price': Decimal('480')}, {'name': 'Tone', 'max_price': Decimal('480')}, {'name': 'Jin', 'max_price': Decimal('480')}]>

       

      總結(jié):

      多表分組模型:

      模型一:  
      Author.objects.values("pk"). annotate(max_price=Max("book__price")). values("name","max_price")   關(guān)鍵字“每一個”后的表.objects.values("分組字段").annotate.(聚合函數(shù)("關(guān)聯(lián)表__統(tǒng)計字段")).values("需要展示的字段")

      模型二:
        Author.objects.all().      annotate(max_price=Max("book__price")).values("name","max_price")
        關(guān)鍵字“每一個”后的表.objects.all().annotate.(聚合函數(shù)("關(guān)聯(lián)表__統(tǒng)計字段")).values("需要展示的字段")
        注意:all()可加可不加,結(jié)果都是一樣的 不同之處在于下面的寫法 values(“”)中的字段可以取根表的所有字段以及統(tǒng)計的字段
      解析:以 關(guān)鍵字“每一個”后的表 為根,通過values()進行分組;
      然后通過分組管理器(annotate)配合聚合函數(shù)獲取“關(guān)聯(lián)表的統(tǒng)計字段”的數(shù)據(jù)
      最后使用values("字段")獲取需要的字段數(shù)據(jù)

       

      extra方法:

      在Django中,有些時間查詢語句是ORM無法完成轉(zhuǎn)換的,就像獲取在datatime中的年月日,直接從數(shù)據(jù)庫是無法查詢的,我們可以個extra方法

      格式: extra(select = {"自定義字段":“date_format(‘時間字段’,'%%Y-%%m-%%d')”}): 

      extra是將Queryset對象增加 一個自定義的字段,返回的結(jié)果還是Queryset對象。

      date_list  = Article.objects.filter(user=user).extra(select={"y_m_date":"date_format(create_time,'%%Y/%%m/%%d')"}).values("y_m_date").annotate(c=Count("nid")).values_list("y_m_date","c")
      print(date_list)
      #結(jié)果
      <QuerySet [('2020/03/23', 1)]>

       TruncMonth方法

      除了extra方法之外,Django還給我們封裝了一個”TruncMonth “方法

        from django.db.models.functions import TruncMonth 

       

      在上圖中, TruncMont把“timestamp”進行截取,只截取到月份,然后賦值給month,原理和extra一樣,也是增加了一個鍵值對,返回的也是Queryset對象

          ret = models.Article.objects.filter(user=user).annotate(month=TruncMonth("create_time")).values("month").annotate(
              c=Count("nid")).values_list("month", "c")
          print("ret----->",ret)
          # 結(jié)果
          <QuerySet [(datetime.datetime(2020, 3, 1, 0, 0), 1)]>

       

      ===================== F與Q查詢 ==================

      F查詢:

          # 查詢評論數(shù)大于閱讀數(shù)的書籍
      
          ret = Book.objects.all().filter(comment_num__gt=F("read_num"))
          print(ret)  # <QuerySet [<Book: python>, <Book: go>]>
      
          # 將所有書籍的價格增加20
          ret = Book.objects.update(price=F("price")+20)

       

      Q查詢:

      Q有三種關(guān)聯(lián)方式:且、或、非

      且:和符號  “ & 匹配使用,用戶連接多個參數(shù)

      或:和符號 ”|“ 匹配使用,用于選擇多個條件中的一個

      非:和符號”~“ 匹配使用,用戶否定某條件,后面必須跟 ”|“符號

      示例:

          from django.db.models import Q
      
          # 查詢書名為python 且 價格為120的書籍  python    120
      
        #方式一:正常寫法
       
          ret = Book.objects.filter(title="python",price=220).values("title","price")
          print(ret)  # <QuerySet [{'title': 'python', 'price': Decimal('220.00')}]>

        # 方式二:使用 Q ret = Book.objects.filter(Q(title="python") & Q(price=220)).values("title","price") print(ret) # <QuerySet [{'title': 'python', 'price': Decimal('220.00')}]> # 查詢書名為python 或者 價格為120的書籍 ret = Book.objects.filter(Q(title="python") | Q(price=120)).values("title","price") print(ret) # <QuerySet [{'title': 'python', 'price': Decimal('220.00')}]> # 查詢書名非python 或者 價格為120的書籍 ret = Book.objects.filter(~Q(title="python") | Q(price=120)).values("title","price") print(ret) # <QuerySet [{'title': 'java', 'price': Decimal('600.00')}, {'title': 'go', 'price': Decimal('220.00')}, # {'title': 'lua', 'price': Decimal('12432.00')}]>


      posted @ 2020-03-23 19:16  繁華無殤  閱讀(258)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 青草青草久热精品视频在线播放 | 性欧美VIDEOFREE高清大喷水| 亚洲成人av在线高清| 羞羞影院午夜男女爽爽免费视频 | 嫩草院一区二区乱码| 国产精品无码专区av在线播放| 日韩av一区二区三区精品| 亚洲大尺度无码无码专线| 国产精品成人观看视频国产奇米 | 亚洲国产高清精品线久久| 人妻少妇偷人精品视频| 在线天堂最新版资源| 一区二区三区av天堂| 国产伦精品一区二区三区妓女下载 | 亚洲国产精品日韩av专区| 国产精品v片在线观看不卡| 国产精品亚洲二区在线看| 国产精品一区在线蜜臀| 国产成人午夜精品影院| 男女啪啪免费观看网站| 亚洲精品日韩在线观看| 啪啪av一区二区三区| 人人妻人人狠人人爽天天综合网| 亚洲一国产一区二区三区| 国产精品日日摸夜夜添夜夜添2021| 不卡AV中文字幕手机看| 26uuu另类亚洲欧美日本| 在线精品自拍亚洲第一区| 无码综合天天久久综合网 | 欧美高清一区三区在线专区| 国产精品99久久久久久董美香| 久久国产精品亚洲精品99| 亚洲高清成人av在线| 成年视频人免费网站动漫在线| 亚洲综合av一区二区三区| 日韩av裸体在线播放| 国产精品国产自产拍在线| 婷婷久久香蕉五月综合加勒比 | 日日碰狠狠躁久久躁96avv| 特黄三级又爽又粗又大| 日本一本无道码日韩精品|