1. 程式人生 > >Django 中ORM的高階查詢用法

Django 中ORM的高階查詢用法

from django.shortcuts import render
from django.http import HttpResponse
from datetime import date

from .models import *

def select(request):
    # 1.單表資料查詢
    # 查詢id>1且id<3的所有出版社
    # id_lte:小於等於  id_gte:大於等於
    results = Publication.objects.filter(id__lt=3, id__gt=1)

    results = Publication.objects.filter(id__in=[1,2])
    # 查詢id!=1的出版社.exclude():取反
    results = Publication.objects.exclude(id__in=[1])

    # 包含關係查詢:比如查詢出版社名稱中含有"新"的出版社
    results = Publication.objects.filter(name__contains='新')
    '''
    name__startswith='新':查詢name欄位的值以"新"開頭的Model物件
    name__endswith='新':查詢name欄位的值以"新"結尾的Model物件
    name__istartswith='新':查詢name欄位的值以"新"開頭的Model物件.(如果值是英文,忽略大小寫)
    
    '''

    # 查詢2018年的所有資料
    results = Publication.objects.filter(create_time__year=2018)
    # 查詢某一個時間範圍內的資料
    start_time = date(2018,10,1)
    end_time = date(2018,11,16)
    results = Publication.objects.filter(create_time__range=(start_time,end_time))
    # 查詢2018年以後的資料
    start_time = date(2018,1,1)
    result = Publication.objects.filter(create_time__gt=start_time)

    for result in results:
        print(result.name)

    return HttpResponse('ok')

# 引入Django內建的統計函式:求平均值、最大值、最小值、組內資料個數、求和
from django.db.models import Avg,Max,Min,Count,Sum
def annotate(request):
    '''
    資料的分組查詢,指的就是根據某一個表中的欄位,對所有資料進行分組,然後再對分組之後的資料進行操作
    :param request:
    :return:
    '''
    # 1.單表的分組查詢
    # 圖書表:Book。將圖書表中的所有資料,按照圖書的級別進行分組,統計每一個分組中的資料個數
    # Book.objects.values('level'):將資料按照level的值進行分組,分完組以後,再呼叫annotate進行資料的統計
    # {'level': '中級', 'level__count': 1}, {'level': '初級', 'level__count': 2}, {'level': '高階', 'level__count': 1}
    result = Book.objects.values('level').annotate(Count('level'))

    # 先按照級別分組,再統計每一個分組的價格平均值。
    # {'level': '中級', 'price__avg': 150.0}, {'level': '初級', 'price__avg': 115.25}, {'level': '高階', 'price__avg': 180.5}
    # price__avg: 價格欄位price + 統計函式Avg  共同組成這個鍵
    result = Book.objects.values('level').annotate(Avg('price'))

    result = Book.objects.values('level').annotate(avg_price = Avg('price'))


    # 先按照級別分組,再統計每一個分組的個數,最後再按照個數進行升序/降序排列
    result = Book.objects.values('level').annotate(count=Count('level')).order_by('count')   # ('-count')
    # for r in result:
    #     print(r['count'])

    # 2.多表聯查
    # 查詢圖書表:按照出版社進行分組,然後在統計這個出版社出版的個數
    result = Book.objects.values('publication').annotate(count=Count('publication'))



    # a. 統計每一個出版社中價格最低的圖書
    result = Book.objects.values('publication').annotate(min=Min('price'))
    # b. 統計出出版社出版圖書數量大於1的圖書資訊;
    result = Book.objects.values('publication').annotate(count=Count('publication'))
    for r in result:
        if r['count']>1:
            print(r['publication'])
            results = Book.objects.filter(publication_id=r['publication'])
            for res in results:
                print('圖書ID:{}  圖書名稱:{}  圖書價格:{}  圖書級別:{}  所屬出版社:{}'.format(res.id,res.name,res.price,res.level,res.publication))

    # c. 統計每一個出版社出版所有圖書的總價格;
    result = Book.objects.values('publication').annotate(sum=Sum('price'))
# 3365    10.17
# 2116.16
# 2616
    return HttpResponse('ok')