Django聚合查詢、分組查詢、F與Q查詢


表查詢

基於django settings源碼實現自己的項目
配置文件的可插拔式設計
	dir()
	importlib
	反射

單表查詢
    只要是queryset對象 就可以無限制的點擊queryset對象的方法
	13條
		1.all()  # 查所有
		2.filter()  # 根據條件過濾 多個條件之間是and關系
        3.get()  # 直接獲取數據對象  查詢條件不存在直接報錯
        4.first()  # 取queryset的第一個數據對象
        5.last()  # 取queryset的最后一個數據對象
        6.exclude()  # 除此之外 
        7.values()  # queryset 類似於列表套字典
        8.values_list()  # queryset 類似於列表套元組
        9.count()  # 統計數據個數
        10.distinct()  # 一定要是完全一樣的數據才能去重
        11.order_by()  # 排序 默認是升序 加負號就變成降序
        12.reverse()  # 反轉 排序之后才能反轉
        13.exists()  # 判斷queryset是否有值 結果是個布爾值
        
	神奇的雙下線的查詢
        price__gt
        price__lt
        price__gte
        price__lte
        price__in=[100,200,300]
        price__range=(200,800)
        title__contains  包含  模糊匹配
        title__icontains  忽略大小寫
        publish_date__year  只針對年份
        publish_date__month  只針對月份
        title__startswith
        title__endswith 


多表查詢
    前期表准備
        圖書管理系統
            一對多
            多對多
            一對一
        
	外鍵字段的增刪改查
        一對多字段
            create(publish_id=1)
            create(publish=publish_obj)
            
            update(publish_id=2)
            update(publish=publish_obj1)
            
            models.Publish.objects.filter(pk=2).delete()
            # orm外鍵默認是級聯更新 級聯刪除的
        
        多對多字段
            # 朝第三張關系表中添加數據
            book_obj.authors.add(1)
            book_obj.authors.add(1,2,3,4)
            book_obj.authors.add(author_obj)
            book_obj.authors.add(author_obj,author_obj1,author_obj2)
            # 朝第三張表修改數據
            book_obj.authors.set((1,))
            book_obj.authors.set((1,2,3))
            book_obj.authors.set((author_obj,))
            book_obj.authors.set((author_obj,author_obj1))
            # 朝第三張表刪除關系
            book_obj.authors.remove(1)
            book_obj.authors.remove(1,2,3,4)
            book_obj.authors.remove(author_obj)
            book_obj.authors.remove(author_obj,author_obj1)
            # 朝第三張表清空當前書籍對象所有的記錄
            book_obj.authors.clear()
            
	跨表查詢
        正反向的概念:
            外鍵字段在誰那兒 誰就是正向
            沒有外鍵字段的  就是反向

        口訣:
            正向查詢按字段
            反向查詢按表名小寫


		基於對象  # 子查詢
            """
            步驟都是先獲取一個數據對象
            然后利用對象點點點的方式查到鎖對應的數據
            """
            # 正向
            book_obj.publish.name
            
            book_obj.authors.all()
            
            author_obj.author_detail.addr
            """
            外鍵字段所對應的數據 如果是單個 不需要加all
            如果是多個 需要加all()
            """
            # 反向
            publish_obj.book_set.all()
            
            author_obj.book_set.all()
            
            author_detail_obj.author.name
            """
            反向查詢 數據如果是多個
            那么需要 表名小寫_set.all()
            如果是一個  直接表名小寫即可
            """ 
  
		基於雙下划綫  # 連表查詢
            """
            left join
            right join
            inner join
            union
            """
            # 正向
            models.Book.objects.filter(title='python').values('publish__name')
            # 寫外鍵字段publish之后 就會跨到publish表中  你想要該表的哪個字段對應的數據  就加__字段名獲取
            
            models.Book.objecst.filter(pk=1).values('authors__name')
            
            models.Author.objects.filter(name='jason').values('author_detail__addr')
            
            models.Publish.objects.filter(pk=1).values('book__title')
            models.authors.objects.filter(pk=1).values('book__title')
            models.AuthorDetail.objects.filter(pk=1).values('author__name')

            # 反向
            
            models.Publish.objects.filter(book__title='python').values('name')

            """查詢書籍id為1 的作者的 手機號"""
            models.Book.objects.filter(pk=1).values('authors__author_detail__phone')



聚合查詢
    聚合函數
        from django.db.models import Max,Min,Sum,Count,Avg
        
        


分組查詢

F與Q查詢

orm中常見字段
    AutoField(primary_key=True)
    CharField(max_length=32)   varchar(32)
    IntegerField()             int
    BigIntegerField()          long
    DateField()
        auto_now:每次修改數據的時候 都會更新該字段
        auto_now_add:只在創建數據的時候 才會自動將創建時間添加 后續不會再自動修改了
    DecimalField()
    BooleanField(Field)
        - 布爾值類型
        該字段在存儲數據的時候 你只需要傳布爾值即可
        對應到數據庫中 會變成0/1
    TextField(Field)
        - 文本類型
        存大段文本
    EmailField(CharField)               varchar(...)
    FileField(Field)
        - 字符串,路徑保存在數據庫,文件上傳到指定目錄
        - 參數:
            upload_to = ""      上傳文件的保存路徑
            storage = None      存儲組件,默認django.core.files.storage.FileSystemStorage

    DecimalField(Field)
    - 10進制小數
    - 參數:
        max_digits,小數總長度
        decimal_places,小數位長度


自定義char字段
    # 自定義char類型字段
    class MyCharField(models.Field):
        def __init__(self,max_length,*args,**kwargs):
            self.max_length = max_length
            super().__init__(max_length=max_length,*args,**kwargs)

        def db_type(self, connection):
            return 'char(%s)'%self.max_length

如果你使用的是django2.X版本 你在建數據庫表關系的時候
你需要手動指定兩個參數
    (你要手動告訴django  級聯更新 級聯刪除  是否建外鍵約束)
    
    on_delete
    db_constraint

!!!!!!!!!!碎片化學習!!!!!!!


查詢優化(面試比較喜歡問的)
    only與defer

    select_related和prefetch_related


django orm中的事務操作
    ACID
        原子性
        一致性
        隔離性
        持久性

        commit
        rollback
    要么同時成功要么同時失敗
    
    from django.db import transaction
    with transaction.atomic():
        # 在該代碼塊中所寫的orm語句 同屬於一個事務
    # 縮進出來之后自動結束

聚合查詢(aggregate)

from django.db.models import Max,Min,Count,Avg,Sum   #查詢總和,平均,最大,最小

res = models.Book.objects.aggregate(Sum('price'))
res1 = models.Book.objects.aggregate(Avg('price'))
res2 = models.Book.objects.aggregate(Count('price'))
res3 = models.Book.objects.aggregate(Max('price'))
res4 = models.Book.objects.aggregate(Min('price'))
res5 = models.Book.objects.aggregate(Max('price'),Min('price'),Count('pk'),Avg('price'),Sum('price'))  #也可以放在一個里面寫

分組查詢 (annotate)

 1.統計每一本書的作者個數

from django.db.models import Max, Min, Count, Avg, Sum

res = models.Book.objects.annotate(author_num = Count('authors')).values('author_num','title')
 #book表根據authors分組求和,author_num是取的別名,values是控制台打印的值
2.統計每個出版社賣的最便宜的書的價格

res = models.Publish.objects.annotate(mmp = Min('book__price')).values('name','mmp')
3.統計不止一個作者的圖書

res = models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1)
4.查詢每個作者出的書的總價格

res = models.Author.objects.annotate(sp=Sum('book__price')).values('name','sp')

F查詢與Q查詢

F查詢的本質就是從數據庫中獲取某個字段的值,之前查詢等號后面的條件都是我們人為輸入的,現在變成了需要從數據庫中獲取數據放在等號后面

查詢庫存量大於賣出量的書籍

from django.db.models import F
res = models.Book.objects.filter(kucun__gt=F('maichu')) #kucun和maichu都是Book表的字段

將書籍庫存數全部增加1000

models.Book.objects.update(kucun=F('kucun')+1000)

把所有書名后面加上'新款'

from django.db.models.functions import Concat
from django.db.models import Value

ret3 = models.Book.objects.update(title=Concat(F('title'), Value('新款')))
models.Book.objects.update(title = F('title')+'新款')  # 不能這么寫

Q查詢 (filter里面條件都是與,Q支持與或非)

查詢書籍名稱是三國演義或者價格是444

from django.db.models import Q
res = models.Book.objects.filter(title='三國演義',price=444.44)  # filter只支持and關系
res1 = models.Book.objects.filter(Q(title='三國演義'),Q(price=444))  # 如果用逗號 那么還是and關系
res2 = models.Book.objects.filter(Q(title='三國演義')|Q(price=444))   #或者關系
res3 = models.Book.objects.filter(~Q(title='三國演義')|Q(price=444))  #查詢除了title是三國演義,或者價格是444的書籍

Q的高級用法

from django.db.models import Q
q = Q()
q.connector = 'or'  # 修改查詢條件的關系   默認是and
q.children.append(('title__contains','三國演義'))  # 往列表中添加篩選條件
q.children.append(('price__gt',444))  # 往列表中添加篩選條件
res = models.Book.objects.filter(q)  # filter支持你直接傳q對象  但是默認還是and關系
print(res)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM