1. 程式人生 > >Django模型(模型成員 模型查詢)

Django模型(模型成員 模型查詢)

模型成員

類的屬性 1.objects:是Manager型別的物件,用於與資料庫進行互動 2.當定義模型類時沒有指定管理器,則Django會為模型類提供一個名為objects的管理器 3.支援明確指定模型類的管理器

class BookInfo(models.Model):
    ...
    books = models.Manager()

4.當為模型類指定管理器後,django不再為模型類生成名為objects的預設管理器

管理器Manager

1.管理器是Django的模型進行資料庫的查詢操作的介面,Django應用的每個模型都擁有至少一個管理器 2.自定義管理器類主要用於兩種情況 a)情況一:向管理器類中新增額外的方法:見下面“建立物件”中的方式二 b)情況二:修改管理器返回的原始查詢集:重寫get_queryset()方法

class BookInfoManager(models.Manager):
    def get_queryset(self):
        return super(BookInfoManager, self).get_queryset().filter(isDelete=False)
class BookInfo(models.Model):
    ...
    books = BookInfoManager()

建立物件 1.當建立物件時,django不會對資料庫進行讀寫操作 2.呼叫save()方法才與資料庫互動,將物件儲存到資料庫中 3.使用關鍵字引數構造模型物件很麻煩,推薦使用下面的兩種之式 說明: _init _方法已經在基類models.Model中使用,在自定義模型中無法使用, a)方式一:在模型類中增加一個類方法

class BookInfo(models.Model):
    ...
    @classmethod
    def create(cls, title, pub_date):
        book = cls(btitle=title, bpub_date=pub_date)
        book.bread=0
        book.bcommet=0
        book.isDelete = False
        return book
引入時間包:from datetime import *
呼叫:book=BookInfo.create("hello",datetime(1980,10,11));
儲存:book.save()

b)方式二:在自定義管理器中新增一個方法 在管理器的方法中,可以通過self.model來得到它所屬的模型類

class BookInfoManager(models.Manager):
    def create_book(self, title, pub_date):
        book = self.model()
        book.btitle = title
        book.bpub_date = pub_date
        book.bread=0
        book.bcommet=0
        book.isDelete = False
        return book

class BookInfo(models.Model):
    ...
    books = BookInfoManager()
呼叫:book=BookInfo.books.create_book("abc",datetime(1980,1,1))
儲存:book.save()

在方式二中,可以呼叫self.create()建立並儲存物件,不需要再手動save()

class BookInfoManager(models.Manager):
    def create_book(self, title, pub_date):
        book = self.create(btitle = title,bpub_date = pub_date,bread=0,bcommet=0,isDelete = False)
        return book

class BookInfo(models.Model):
    ...
    books = BookInfoManager()
呼叫:book=Book.books.create_book("abc",datetime(1980,1,1))
檢視:book.pk

例項的屬性 1.DoesNotExist:在進行單個查詢時,模型的物件不存在時會引發此異常,結合try/except使用 例項的方法 1.str (self):重寫object方法,此方法在將物件轉換成字串時會被呼叫 2.save():將模型物件儲存到資料表中 3.delete():將模型物件從資料表中刪除

模型查詢

1.查詢集表示從資料庫中獲取的物件集合 2.查詢集可以含有零個、一個或多個過濾器 3.過濾器基於所給的引數限制查詢的結果 4.從Sql的角度,查詢集和select語句等價,過濾器像where和limit子句 5.接下來主要討論如下知識點 a)查詢集 b)欄位查詢:比較運算子,F物件,Q物件 查詢集 1.在管理器上呼叫過濾器方法會返回查詢集 2.查詢集經過過濾器篩選後返回新的查詢集,因此可以寫成鏈式過濾 3.惰性執行/懶載入:建立查詢集不會帶來任何資料庫的訪問,直到呼叫資料時,才會訪問資料庫 4.何時對查詢集求值:迭代,序列化,與if合用 5.返回查詢集的方法,稱為過濾器

all()
filter()
exclude()
order_by()
values():一個物件構成一個字典,然後構成一個列表返回

寫法:

filter(鍵1=值1,鍵2=值2)
等價於
filter(鍵1=值1).filter(鍵2=值2)

6.返回單個值的方法

get():返回單個滿足條件的物件
如果未找到會引發"模型類.DoesNotExist"異常
如果多條被返回,會引發"模型類.MultipleObjectsReturned"異常
count():返回當前查詢的總條數
first():返回第一個物件
last():返回最後一個物件
exists():判斷查詢集中是否有資料,如果有則返回True

7.限制查詢集

查詢集返回列表,可以使用下標的方式進行限制,等同於sql中的limit和offset子句 注意:不支援負數索引 使用下標後返回一個新的查詢集,不會立即執行查詢 如果獲取一個物件,直接使用[0],等同於[0:1].get(),但是如果沒有資料,[0]引發IndexError異常,[0:1].get()引發DoesNotExist異常

8.查詢集的快取

每個查詢集都包含一個快取來最小化對資料庫的訪問 在新建的查詢集中,快取為空,首次對查詢集求值時,會發生資料庫查詢,django會將查詢的結果存在查詢集的快取中,並返回請求的結果,接下來對查詢集求值將重用快取的結果

情況一:這構成了兩個查詢集,無法重用快取,每次查詢都會與資料庫進行一次互動,增加了資料庫的負載

print([e.title for e in Entry.objects.all()])
print([e.title for e in Entry.objects.all()])

情況二:兩次迴圈使用同一個查詢集,第二次使用快取中的資料

querylist=Entry.objects.all()
print([e.title for e in querylist])
print([e.title for e in querylist])

何時查詢集不會被快取:當只對查詢集的部分進行求值時會檢查快取,但是如果這部分不在快取中,那麼接下來查詢返回的記錄將不會被快取,這意味著使用索引來限制查詢集將不會填充快取,如果這部分資料已經被快取,則直接使用快取中的資料

欄位查詢

實現where子名,作為方法filter()、exclude()、get()的引數

1.語法:屬性名稱__比較運算子=值

表示兩個下劃線,左側是屬性名稱,右側是比較型別 對於外來鍵,使用“屬性名_id”表示外來鍵的原始值 轉義:like語句中使用了%與,匹配資料中的%與,在過濾器中直接寫,例如:filter(title__contains="%")=>where title like ‘%%%’,表示查詢標題中包含%的

2.比較運算子

exact:表示判等,大小寫敏感;如果沒有寫“ 比較運算子”,表示判等

filter(isDelete=False)

contains:是否包含,大小寫敏感

exclude(btitle__contains='傳')

startswith、endswith:以value開頭或結尾,大小寫敏感

exclude(btitle__endswith='傳')

isnull、isnotnull:是否為null

filter(btitle__isnull=False)

在前面加個i表示不區分大小寫,如iexact、icontains、istartswith、iendswith in:是否包含在一些值內

filter(pk__in=[1, 2, 3, 4, 5])

range:是否包含在範圍內

filter(pk__range=[1,5])

gt、gte、lt、lte:大於、大於等於、小於、小於等於

filter(id__gt=3)

year、month、day、week_day、hour、minute、second:對日期間型別的屬性進行運算

filter(bpub_date__year=1980)
filter(bpub_date__gt=date(1980, 12, 31))

跨關聯關係的查詢:處理join查詢 語法:模型類名 <屬性名> <比較> 注:可以沒有__<比較>部分,表示等於,結果同inner join 可返向使用,即在關聯的兩個模型中都可以使用

filter(heroinfo__hcontent__contains='八')

查詢的快捷方式:pk,pk表示primary key,預設的主鍵是id

filter(pk__lt=6)

聚合函式 aggregate(聚合函式)和annotate(在aggregate的基礎上進行GROUP BY操作) 函式:Avg,Count,Max,Min,Sum

from django.db.models import Max
maxDate = queryset.aggregate(Max('bpub_date'))
HeroInfo.objects.values_list('hbookinfo_id').annotate(Count('id'))

count的一般用法

count = list.count()

F物件

可以使用模型的欄位A與欄位B進行比較,如果A寫在了等號的左邊,則B出現在等號的右邊,需要通過F物件構造
list.filter(bread__gte=F('bcommet'))

django支援對F()物件使用算數運算
list.filter(bread__gte=F('bcommet') * 2)

F()物件中還可以寫作“模型類__列名”進行關聯查詢
list.filter(isDelete=F('heroinfo__isDelete'))

對於date/time欄位,可與timedelta()進行運算
list.filter(bpub_date__lt=F('bpub_date') + timedelta(days=1))

Q物件

過濾器的方法中關鍵字引數查詢,會合併為And進行
需要進行or查詢,使用Q()物件
Q物件(django.db.models.Q)用於封裝一組關鍵字引數,這些關鍵字引數與“比較運算子”中的相同
from django.db.models import Q
list.filter(Q(pk_ _lt=6))

Q物件可以使用&(and)、|(or)操作符組合起來,當操作符應用在兩個Q物件時,會產生一個新的Q物件
list.filter(pk_ _lt=6).filter(bcommet_ _gt=10)
list.filter(Q(pk_ _lt=6) | Q(bcommet_ _gt=10))

使用~(not)操作符在Q物件前表示取反
list.filter(~Q(pk__lt=6))

可以使用&|~結合括號進行分組,構造做生意複雜的Q物件

過濾器函式可以傳遞一個或多個Q物件作為位置引數,如果有多個Q物件,這些引數的邏輯為and

過濾器函式可以混合使用Q物件和關鍵字引數,所有引數都將and在一起,Q物件必須位於關鍵字引數的前面