1. 程式人生 > >django模型系統(二)

django模型系統(二)

har art 管理 [] sele utc .cn ext 區分

本文轉載自https://blog.csdn.net/xiaogeldx/article/details/87927345

常用的模型字段類型

  • 模型的類對應的是數據庫中的表,模型的類屬性對應表的字段

    Field的常用參數

  • 參考文檔:https://docs.djangoproject.com/en/2.1/ref/models/fields/#field-options
  • primary_key:指定是否為主鍵,通常不用自己定義,django會自動創建
  • unique:指定是否唯一
  • null:指定是否為空,默認為False
  • blank:等於True時form表單驗證時可以為空,默認為False
  • default:設置默認值
  • DateField.auto_now:每次修改都會將當前時間更新進去
  • DateField.auto_now_add:第一次添加進去,都會將當前時間設置進去,以後修改,不會修改這個值

    常用的字段類型

  • 參考文檔:https://docs.djangoproject.com/en/2.1/ref/models/fields/#field-types
  • IntegerField:整型,映射到數據庫中的int類型
  • CharField:字符類型,映射到數據庫中的varchar類型,通過max_length指定最大長度
  • Auto_Field:自動遞增的整數字段,通常不會用(因為通常不自定義主鍵)
  • TextField:文本類型,映射到數據庫中的longtext類型
  • BooleanField:布爾類型,映射到數據庫中的tinyint類型,在使用的時候,傳遞True/False進去,如果要可以為空,則用NullBooleanField
  • DateField:日期類型,沒有時間,映射到數據庫中是date類型,在使用的時候可以設置DateField.auto_now每次保存對象時,自動設置該字段為當前時間,設置DateField.auto_now_add當對象第一次被創建時自動設置當前時間
  • DateTimeField:日期時間類型,映射到數據庫中的是datetime類型,在使用的時候,傳遞datetime.datetime()進去

    常用的字段類型映射

    int--------------------------IntegetField
    varchar----------------------CharField
    longtext----------------------TextField

    date--------------------------DateField
    datetime--------------DateTimeField

    常用查詢

  • 通過模型類上的管理器(Student.objects)來構造QuerySet
  • QuerySet表示數據庫中對象的集合,等同於MySQL中的select語句,惰性的
  • 獲取單個對象
    • first()獲取第一條數據,返回對象
    • last()獲取最後一條數據,返回對象
      技術分享圖片
    • get(**kwargs)根據給定的條件,獲取一個對象,如果有多個對象符合或者沒有對象符合,會報錯,返回對象
      技術分享圖片
  • 獲取QuerySet
    • all()獲取所有記錄,返回的是QuerySet
      技術分享圖片
    • filter(**kwargs)根據給定的條件,獲取符合條件的過濾後的QuerySet,多個條件時使用and連接

        In [19]: res = Student.objects.filter(age=17,sex=0)    #選出age=17 and sex=0的數據                                                                                
        In [21]: res                                                                                                                           
        Out[21]: <QuerySet [<Student: na-17>]>
    • exclude(**kwargs)根據給定的條件,獲取不符合條件的過濾後的QuerySet,和filter使用方法一致,作用剛好相反,它是排除

        In [24]: res = Student.objects.exclude(sex=0,age=16) #除了age=16 and sex=0的數據,剩下的都要                                                                                   
        In [25]: res                                                                                                                           
        Out[25]: <QuerySet [<Student: xiaoge-16>, <Student: na-17>, <Student: long-19>, <Student: di-18>]>  #因為沒有符合條件的數據,所以都取
    • 多條件的or連接,用到Q對象,django.db.models.Q

        In [27]: from django.db.models import Q                                                                                                
        In [28]: Student.objects.filter(Q(sex=0)|Q(sex=1)) #獲取性別是男或者是女                                                                                    
        Out[28]: <QuerySet [<Student: xiaoge-16>, <Student: na-17>, <Student: long-19>, <Student: di-18>]>  #所有數據都符合
    • values(*fields)指定字段(可以多個字段),返回一個QuerySet(QuerySet裏是字典列表,而不是數據對象),後面還可以加n個filter()

        In [34]: res = Student.objects.values('name','sex').filter(age=17)                                                                     
        In [35]: res                                                                                                                           
        Out[35]: <QuerySet [{'name': 'na', 'sex': 0}]>
        In [36]: res = Student.objects.values('name','age').filter(age=17).filter(sex=0)                                                       
        In [37]: res                                                                                                                           
        Out[37]: <QuerySet [{'name': 'na', 'age': 17}]>

技術分享圖片
- only(*)返回QuerySet(裏面是對象列表),一定包含主鍵字段,only用的比較多,可以指定很少的字段,高效

    In [38]: res = Student.objects.only('name','age').filter(sex=0)                                                                        
    In [39]: res                                                                                                                           
    Out[39]: <QuerySet [<Student: na-17>, <Student: di-18>]>
    In [40]: print(res.query)                                                                                                              
    SELECT `students_student`.`id`, `students_student`.`name`, `students_student`.`age` FROM `students_student` WHERE `students_student`.`sex` = 0  #主鍵id
    In [41]: res = Student.objects.only('name','age').filter(sex=0).filter(name='di')                                                      
    In [42]: res                                                                                                                           
    Out[42]: <QuerySet [<Student: di-18>]>
    In [43]: res[0].c_time                                                                                                                 
    Out[43]: datetime.datetime(2019, 2, 26, 0, 27, 28, 626041, tzinfo=<UTC>)
  • defer(*fields)返回一個QuerySet,和only用法一樣,作用相反,fields是指定排除的字段

      In [44]: res = Student.objects.defer('c_time','age')                                                                                   
      In [46]: print(res.query)                                                                                                              
      SELECT `students_student`.`id`, `students_student`.`name`, `students_student`.`sex`, `students_student`.`qq`, `students_student`.`phone`, `students_student`.`e_time` FROM `students_student`
    • order_by(*fields)根據給定字段來排序

        In [47]: res = Student.objects.order_by('c_time').only('name')                                                                         
        In [48]: res                                                                                                                           
        Out[48]: <QuerySet [<Student: xiaoge-16>, <Student: na-17>, <Student: long-19>, <Student: di-18>]>
        In [49]: print(res.query)                                                                                                              
        SELECT `students_student`.`id`, `students_student`.`name` FROM `students_student` ORDER BY `students_student`.`c_time` ASC
    • order_by(*-fields)根據給定字段來倒序(和正序唯一區別是在字段名前加個負號)

        In [52]: res = Student.objects.order_by('-c_time').only('name')                                                                        
        In [53]: print(res.query)                                                                                                              
        SELECT `students_student`.`id`, `students_student`.`name` FROM `students_student` ORDER BY `students_student`.`c_time` DESC
        In [54]: res                                                                                                                           
        Out[54]: <QuerySet [<Student: di-18>, <Student: long-19>, <Student: na-17>, <Student: xiaoge-16>]>
    • 切片,和Python列表切片用法相似,不支持負索引,數據量大時不用步長
      切片後不再支持附加過濾條件與排序

        In [55]: res = Student.objects.all()[:2]                                                                                               
        In [56]: res                                                                                                                           
        Out[56]: <QuerySet [<Student: xiaoge-16>, <Student: na-17>]>
        In [57]: res = Student.objects.all()[2:3]                                                                                              
        In [58]: res                                                                                                                           
        Out[58]: <QuerySet [<Student: long-19>]>
        In [59]: print(res.query)                                                                                                              
        SELECT `students_student`.`id`, `students_student`.`name`, `students_student`.`age`, `students_student`.`sex`, `students_student`.`qq`, `students_student`.`phone`, `students_student`.`c_time`, `students_student`.`e_time` FROM `students_student`  LIMIT 1 OFFSET 2  
        In [60]: res = Student.objects.all()[1:3]                                                                                              
        In [61]: print(res.query)                                                                                                              
        SELECT `students_student`.`id`, `students_student`.`name`, `students_student`.`age`, `students_student`.`sex`, `students_student`.`qq`, `students_student`.`phone`, `students_student`.`c_time`, `students_student`.`e_time` FROM `students_student`  LIMIT 2 OFFSET 1      *offset偏移坐標,偏移的位置
        In [62]: res = Student.objects.all()[::1]                                                                                              
        In [63]: res                                                                                                                           
        Out[63]: [<Student: xiaoge-16>, <Student: na-17>, <Student: long-19>, <Student: di-18>]

      常用查詢條件

  • 支持filter,exclude,get
  • exact準確匹配(__exact)

      In [65]: res = Student.objects.filter(id__exact=13)                                                                                    
      In [66]: res                                                                                                                           
      Out[66]: <QuerySet [<Student: di-18>]>
  • iexact模糊匹配,不區分大小寫(__iexact)

      In [67]: res = Student.objects.filter(name__iexact='XIAOGE')                                                                           
      In [69]: res                                                                                                                           
      Out[69]: <QuerySet [<Student: xiaoge-16>]>
  • contains包含,在首尾亦可(__contains)

      In [71]: res = Student.objects.filter(name__contains='ao')                                                                             
      In [72]: print(res.query)                                                                                                              
      SELECT `students_student`.`id`, `students_student`.`name`, `students_student`.`age`, `students_student`.`sex`, `students_student`.`qq`, `students_student`.`phone`, `students_student`.`c_time`, `students_student`.`e_time` FROM `students_student` WHERE `students_student`.`name` LIKE BINARY %ao%
      In [73]: res                                                                                                                           
      Out[73]: <QuerySet [<Student: xiaoge-16>]>
    技術分享圖片
  • icontains不區分大小寫的包含(__icontains)

      In [74]: res = Student.objects.filter(name__icontains='ON')                                                                            
      In [75]: res                                                                                                                           
      Out[75]: <QuerySet [<Student: long-19>]>
  • in給定一個可叠代的對象(列表,元組,QuerySet)

      In [76]: res = Student.objects.filter(name__in=['xiaoge','小哥','aaa'])                                                                
      In [77]: res                                                                                                                           
      Out[77]: <QuerySet [<Student: xiaoge-16>]>
      In [78]: print(res.query)                                                                                                              
      SELECT `students_student`.`id`, `students_student`.`name`, `students_student`.`age`, `students_student`.`sex`, `students_student`.`qq`, `students_student`.`phone`, `students_student`.`c_time`, `students_student`.`e_time` FROM `students_student` WHERE `students_student`.`name` IN (xiaoge, 小哥, aaa)
  • range範圍

      In [79]: res = Student.objects.filter(age__range=(16,19))                                                                              
      In [80]: res                                                                                                                           
      Out[80]: <QuerySet [<Student: xiaoge-16>, <Student: na-17>, <Student: long-19>, <Student: di-18>]>
      In [81]: print(res.query)                                                                                                              
      SELECT `students_student`.`id`, `students_student`.`name`, `students_student`.`age`, `students_student`.`sex`, `students_student`.`qq`, `students_student`.`phone`, `students_student`.`c_time`, `students_student`.`e_time` FROM `students_student` WHERE `students_student`.`age` BETWEEN 16 AND 19
  • gt大於,gte大於等於,lt小於,lte小於等於

      In [82]: res = Student.objects.filter(age__gt=18)                                                                                      
      In [83]: res                                                                                                                           
      Out[83]: <QuerySet [<Student: long-19>]>
      In [84]: res = Student.objects.filter(age__gte=18)                                                                                     
      In [85]: res                                                                                                                           
      Out[85]: <QuerySet [<Student: long-19>, <Student: di-18>]>
      In [86]: res = Student.objects.filter(age__lte=18)                                                                                     
      In [87]: res                                                                                                                           
      Out[87]: <QuerySet [<Student: xiaoge-16>, <Student: na-17>, <Student: di-18>]>
      In [88]: res = Student.objects.filter(age__lt=18)                                                                                      
      In [89]: res                                                                                                                           
      Out[89]: <QuerySet [<Student: xiaoge-16>, <Student: na-17>]>
    技術分享圖片
  • startswith以...開頭,大小寫敏感,istartswith,不區分大小寫
  • endswith以...結尾,區分大小寫,iendswith,不區分大小寫

      In [90]: res = Student.objects.filter(name__startswith='xi')                                                                           
      In [91]: res                                                                                                                           
      Out[91]: <QuerySet [<Student: xiaoge-16>]>
      In [92]: res = Student.objects.filter(name__endswith='na')                                                                             
      In [93]: res                                                                                                                           
      Out[93]: <QuerySet [<Student: na-17>]>
      In [94]: res = Student.objects.filter(name__iendswith='NG')                                                                            
      In [95]: res                                                                                                                           
      Out[95]: <QuerySet [<Student: long-19>]>
    技術分享圖片
  • isnull,值為True或False,對應MySQL中的IS NULL和IS NOT NULL,判斷是否為空

      In [97]: res = Student.objects.filter(name__isnull=True)                                                                               
      In [98]: res                                                                                                                           
      Out[98]: <QuerySet []>
      In [99]: res = Student.objects.filter(name__isnull=False)                                                                              
      In [100]: res                                                                                                                          
      Out[100]: <QuerySet [<Student: xiaoge-16>, <Student: na-17>, <Student: long-19>, <Student: di-18>]>

    聚合與分組

    聚合

  • from django.db.models import Count,Avg,Max,Min,Sum
  • 通過QuerySet的aggregate方法
  • count統計數量,Avg平均值,Max最大值,Min最小值,Sum求和

      In [102]: Student.objects.all().count()                                                                                                
      Out[102]: 4
      In [103]: Student.objects.filter(age__gt=16).count()                                                                                   
      Out[103]: 3
      In [104]: from django.db.models import Avg,Count,Max,Min,Sum                                                                           
      In [105]: Student.objects.aggregate(age_avg=Avg('age'))                                                                                
      Out[105]: {'age_avg': 17.5}
      In [106]: Student.objects.filter(sex=1).aggregate(max_avg=Max('age'))                                                                  
      Out[106]: {'max_avg': 19}
      In [107]: Student.objects.filter(sex=0).aggregate(age_min=Min('age'))                                                                  
      Out[107]: {'age_min': 17}
      In [108]: Student.objects.filter(sex=0).aggregate(age_sum=Sum('age'))                                                                  
      Out[108]: {'age_sum': 35}

    技術分享圖片

    分組,聚合

  • 結合Values,annotate和聚合方法一起實現

      #查詢男生女生分別是多少個
      In [109]: Student.objects.values('sex').annotate(num=Count('sex'))                                                                     
      Out[109]: <QuerySet [{'sex': 1, 'num': 2}, {'sex': 0, 'num': 2}]>
      In [110]: Student.objects.values('sex').annotate(Count('sex'))                                                                         
      Out[110]: <QuerySet [{'sex': 1, 'sex__count': 2}, {'sex': 0, 'sex__count': 2}]>

    技術分享圖片

django模型系統(二)