django中的模型查詢
Django中模型查詢
1,定義屬性
Django根據屬性的型別確定以下資訊:
- 當前選擇的資料庫支援欄位的型別
- 渲染管理表單時使用的預設html控制元件
- 在管理站點最低限度的驗證
django會為表建立自動增長的主鍵列,每個模型只能有一個主鍵列,如果使用選項設定某屬性為主鍵列後django不會再建立自動增長的主鍵列。
- 預設建立的主鍵列屬性為id,可以使用pk代替,pk全拼為primary key。
- 注意:pk是主鍵的別名,若主鍵名為id2,那麼pk是id2的別名。
屬性命名限制:
- 不能是python的保留關鍵字。
- 不允許使用連續的下劃線,這是由django的查詢方式決定的
- 定義屬性時需要指定欄位型別,通過欄位型別的引數指定選項,語法如下:
屬性=models.欄位型別(選項)
2,欄位型別
使用時需要引入django.db.models包,欄位型別如下:
- AutoField:自動增長的IntegerField,通常不用指定,不指定時Django會自動建立屬性名為id的自動增長屬性。
- BooleanField:布林欄位,值為True或False。
- NullBooleanField:支援Null、True、False三種值。
- CharField(max_length=字元長度):字串。 引數max_length表示最大字元個數。
- TextField:大文字欄位,一般超過4000個字元時使用。
- IntegerField:整數。
- DecimalField(max_digits=None, decimal_places=None):十進位制浮點數。 ++ 引數max_digits表示總位數。 ++ 引數decimal_places表示小數位數。
- FloatField:浮點數。
- DateField[auto_now=False, auto_now_add=False]):日期。 ++ 引數auto_now表示每次儲存物件時,自動設定該欄位為當前時間,用於”最後一次修改”的時間戳,它總是使用當前日期,預設為false。 ++ 引數auto_now_add表示當物件第一次被建立時自動設定當前時間,用於建立的時間戳,它總是使用當前日期,預設為false。 ++引數auto_now_add和auto_now是相互排斥的,組合將會發生錯誤。
- TimeField:時間,引數同DateField。
- DateTimeField:日期時間,引數同DateField。
- FileField:上傳檔案欄位。
- ImageField:繼承於FileField,對上傳的內容進行校驗,確保是有效的圖片。
3,選項
通過選項實現對欄位的約束,選項如下:
- null:如果為True,表示允許為空,預設值是False。
- blank:如果為True,則該欄位允許為空白,預設值是False。
- 對比:null是資料庫範疇的概念,blank是表單驗證證範疇的。
- db_column:欄位的名稱,如果未指定,則使用屬性的名稱。
- db_index:若值為True, 則在表中會為此欄位建立索引,預設值是False。
- default:預設值。
- primary_key:若為True,則該欄位會成為模型的主鍵欄位,預設值是False,一般作為AutoField的選項使用。
- unique:如果為True, 這個欄位在表中必須有唯一值,預設值是False。
4,欄位查詢
all():返回模型類對應表格中的所有資料。 例:查詢圖書所有資訊。 BookInfo.objects.all();->select * from booktest_bookinfo;
get():返回表格中滿足條件的一條資料。 如果查到多條資料,則拋異常:MultipleObjectsReturned 查詢不到資料,則拋異常:DoesNotExist 例:查詢圖書id為3的圖書資訊。 BookInfo.objects.get(id=3) –> select * from booktest_bookinfo where id = 3;
filter():引數寫查詢條件,返回滿足條件QuerySet集合資料。 條件格式: 模型類屬性名__條件名=值 注意:此處是模型類屬性名,不是表中的欄位名
1. 判等 exact。
例:查詢編號為1的圖書。
BookInfo.object.filter(id=1)
BookInfo.object.filter(id__exact=1)此處的exact可以省略
2. 模糊查詢 like
例:查詢書名包含'傳'的圖書。contains
BookInfo.objects.filter(btitle__contains=’傳’)
例:查詢書名以'部'結尾的圖書 endswith 開頭:startswith
BookInfo.objects.filter(btitle__endswith=’部’)
BookInfo.objects.filter(btitle__startswith=’天’)
3. 空查詢 where 欄位名 isnull
例:查詢書名不為空的圖書。isnull
BookInfo.objects.filter(btitle__isnull=False)
4. 範圍查詢 where id in (1,3,5)
例:查詢編號為1或3或5的圖書。In
BookInfo.objects.filter(id__in=[1,3,5])
5. 比較查詢 gt lt(less than) gte(equal) lte
例:查詢編號大於等於3的圖書。
BookInfo.objects.filter(id__gte=3)
6. 日期查詢
例:查詢1980年發表的圖書。
BookInfo.objects.filter(bpub_date__year = 1980)
例:查詢1980年1月1日後發表的圖。
BookInfo.objects.filter(bpub_date__gt = date(1980,1,1))
7. exclude:返回不滿足條件的資料。
例:查詢id不為3的圖書資訊。
BookInfo.objects.exclude(id=3)123456789101112131415161718192021222324252627282930313233
5,F物件
作用:用於類屬性之間的比較條件。
使用之前需要先匯入:
from django.db.models import F
例:查詢圖書閱讀量大於評論量圖書資訊。where bread > bcomment
BookInfo.objects.filter(bread__gt = F(‘bcomment’))
例:查詢圖書閱讀量大於2倍評論量圖書資訊。
BookInfo.objects.filter(bread__gt=F(‘bcomment’)*2)
6,Q物件
作用:用於查詢時的邏輯條件。可以對Q物件進行&|~操作。
使用之前需要先匯入:
from django.db.models import Q
例:查詢id大於3且閱讀大於30的圖書的資訊。
BookInfo.objects.filter(id__gt=3, bread__gt=30)
BooInfo.objects.filter(Q(id__gt=3) & Q(bread__gt=3))
例:查詢id大於3或者閱讀大於30的圖書的資訊。
BookInfo.objects.filter(Q(id__gt=3) | Q(bread__gt=30))
例:查詢id不等於3圖書的資訊。
BookInfo.objects.filter(~Q(id=3))123456789
7,order_by 返回QuerySet
作用:進行查詢結果進行排序。
例:查詢所有圖書的資訊,按照id從小到大進行排序。
BookInfo.objects.all()order_by('id')
例:查詢所有圖書的資訊,按照id從大到小進行排序。
BookInfo.objects.all().order_by('-id')
例:把id大於3的圖書資訊按閱讀量從大到小排序顯示;
BookInfo.objects.filter(id__gt=3).order_by('-bread')123456
8,聚合函式
作用:對查詢結果進行聚合操作。 sum count max min avg aggregate:呼叫這個函式來使用聚合。
使用前需先匯入聚合類:
from django.db.models import Sum,Count,Max,Min,Avg
例:查詢所有圖書的數目。select count(*) from booktest_bookinfo;
BookInfo.objects.aggregate(Count('id'))
{'id__count': 5} 注意返回值型別及鍵名
例:查詢所有圖書閱讀量的總和。
BookInfo.objects.aggregate(Sum(‘bread’))
{‘bread__sum’:120} 注意返回值型別及鍵名12345678
count函式 作用:統計滿足條件資料的數目。
例:統計所有圖書的數目。
BookInfo.objects.all().count()
例:統計id大於3的所有圖書的數目。
BookInfo.objects.filter(id__gt = 3).count()1234
9,查詢相關函式返回值總結:
get:返回一個物件
all:QuerySet(也就是[])
filter:QuerySet
exclude:QuerySet
order_by:QuerySet
aggregate:字典
count:值1234567
10,查詢集
all, filter, exclude, order_by呼叫這些函式會產生一個查詢集,可以在查詢集上繼續呼叫這些函式。
查詢集特性:
- 1)惰性查詢:只有在實際使用查詢集中的資料的時候才會發生對資料庫的真正查詢。
- 2)快取:當使用的是同一個查詢集時,第一次的時候會發生實際資料庫的查詢,然後把結果快取起來,之後再使用這個查詢集時,使用的是快取中的結果。
限制查詢集:
可以對一個查詢集進行取下標或者切片操作來限制查詢集的結果。
- b[0]就是取出查詢集的第一條資料,
- b[0:1].get()也可取出查詢集的第一條資料。
- 如果b[0]不存在,會丟擲IndexError異常,
- 如果b[0:1].get()不存在,會丟擲DoesNotExist異常。
對一個查詢集進行切片操作會產生一個新的查詢集,下標不允許為負數。
- exists:判斷一個查詢集中是否有資料。 有返回True,沒有返回False
11,模型類關係
1)一對多關係 例:圖書類-英雄類 models.ForeignKey() 定義在多的類中。
2)多對多關係 例:新聞類-新聞型別類 models.ManyToManyField() 定義在哪個類中都可以。
3)一對一關係 例:員工基本資訊類-員工詳細資訊類 models.OneToOneField() 定義在哪個類中都可以。
12,關聯查詢(一對多)
在一對多關係中,一對應的類我們把它叫做一類,多對應的那個類我們把它叫做多類,我們把多類中定義的建立關聯的類屬性叫做關聯屬性。
A、通過物件執行關聯查詢
例:查詢圖書id為1的所有英雄的資訊。
b = BookInfo.objects.get(id=1)
b.heroinfo_set.all()
例:查詢id為1的英雄所屬圖書資訊。
h = HeroInfo.objects.get(id=1)
h.hbook
h.hbook_id12345678
格式:
-
由一類的物件查詢多類的時候:
一類的物件.多類名小寫_set.all() #查詢所用資料
-
由多類的物件查詢一類的時候:
多類的物件.關聯屬性 #查詢多類的物件對應的一類的物件
-
由多類的物件查詢一類物件的id時候:
多類的物件. 關聯屬性_id
B、通過模型類實現關聯查詢:
例:查詢圖書,要求圖書中英雄的描述包含'八'。Join
BookInfo.objects.filter(heroinfo__hcomment__contains='八')
例:查詢圖書,要求圖書中的英雄的id大於3.
BookInfo.objects.filter(heroinfo__id__gt=3)
例:查詢書名為“天龍八部”的所有英雄。
HeroInfo.objects.filter(hbook__btitle = '天龍八部')12345678
格式:
- 通過多類的條件查詢一類的資料:
一類名.objects.filter(多類名小寫__多類屬性名__條件名=值)1
- 通過一類的條件查詢多類的資料:
多類名.objects.filter(關聯屬性__一類屬性名__條件名=值)1
13,自關聯,特殊的一對多的關係
對於地區資訊、分類資訊等資料,表結構非常類似,每個表的資料量十分有限,為了充分利用資料表的大量資料儲存功能,可以可以設計成一張表,內部的關係欄位指向本表的主鍵,這就是自關聯的表結構。
#定義地區模型類,儲存省、市、區縣資訊
class AreaInfo(models.Model):
atitle=models.CharField(max_length=30)
# 關係屬性使用self指向本類,要求null和blank允許為空,因為一級資料是沒有父級的。
aParent=models.ForeignKey('self',null=True,blank=True)1234567
14,管理器
BookInfo.objects.all()->objects是一個什麼東西呢? 答:objects是Django幫我自動生成的管理器,通過這個管理器可以實現對資料的查詢。
objects是models.Manger類的一個物件。自定義管理器之後Django不再幫我們生成預設的objects管理器。
1)自定義一個管理器類,這個類整合models.Manger類。 2)再在具體的模型類裡定義一個自定義管理器類的物件。
自定義管理器類的應用場景:
- 1)改變查詢的結果集。 比如呼叫BookInfo.books.all()返回的是沒有刪除的圖書的資料。
- 2)在管理器類中定義一個方法幫我們建立對應的模型類物件。 使用self.model()就可以建立一個跟自定義管理器對應的模型類物件。
15,元選項
Django預設生成的表名:
應用名小寫_模型類名小寫。
元選項:
需要在模型類中定義一個元類Meta,在裡面定義一個類屬性db_table就可以指定表名。
16,管理器和元選項案例:
# 自定義一個管理器類
class BookInfoManager(models.Manager):
# 重寫父類的all函式, 返回資料表中沒有刪除的資料
# all filter order_by exclude都呼叫get_queryset()函式,單獨重寫
#作用1:改變查詢的結果集
def all(self):
# 1.呼叫父類的方法查詢出所有圖書 QuerySet
res = super().get_queryset().all()
# 2.對結果進行過濾
return res.filter(isDelete=False)
# 作用2:建立對應模型類的物件,並可以進行一些初始化值
def create(self, btitle, bpub_date):
# b = BookInfo()
# 動態建立一個BookInfo類的物件,類名更改之後這句程式碼也不需要變化
b = self.model()
b.btitle = btitle
b.bpub_date = bpub_date
b.bread = 0
b.bcomment = 0
b.isDelete = False
return b
# 一類
# 屬性名 = models.欄位型別(選項)
class BookInfo(models.Model):
btitle = models.CharField(max_length=20, db_column='title')
# btitle = models.CharField(max_length=20, unique=True, db_index=True) #圖書標題
bpub_date = models.DateField(auto_now_add=True) # 出版日期
bread = models.IntegerField(default=0) # 閱讀量
bcomment = models.IntegerField(default=0) # 評論數
isDelete = models.BooleanField(default=False) # 軟刪除
# python自帶的manager類管理器
# books = models.Manager()
# 自定義一個類管理起器物件
objects = BookInfoManager()
# 元選項
class Meta:
db_table = 'bookinfo' # 指定表名,db_table不能變