西遊之路——python全棧——django中orm的使用(2) python---django中orm的使用(1)
阿新 • • 發佈:2018-11-14
目錄
1.基於物件的正向查詢和反向查詢
在python---django中orm的使用(1)中也提到了正向和反向查詢
表:一對多 書籍和出版社
1 class Book(models.Model): 2 title = models.CharField(max_length=100) 3 authors = models.ManyToManyField(Author) 4 publisher = models.ForeignKey(Publisher) 5 publication_date = models.DateField()Book(多)6 price=models.DecimalField(max_digits=5,decimal_places=2,default=10) 7 def __str__(self): 8 return self.title 9 10 Book(多)
================
1 class Publisher(models.Model): 2 name = models.CharField(max_length=30, verbose_name="名稱") 3 address = models.CharField("出版社(一)地址", max_length=50) 4 city = models.CharField('城市',max_length=60) 5 state_province = models.CharField(max_length=30) 6 country = models.CharField(max_length=50) 7 website = models.URLField() 8 9 class Meta: 10 verbose_name = '出版商' 11 verbose_name_plural = verbose_name12 13 def __str__(self): 14 return self.name 15 16 出版社(一)
正向查詢:
from blog import models def data_oper(req): obj = models.Book.objects.filter(id=2)[0] print(obj.publisher.name) print(obj.publisher.city) #正向查詢,正常查詢
反向查詢:
from blog import models def data_oper(req): obj = models.Publisher.objects.filter(id=6)[0] print(obj.book_set.all().values("title").distinct()) #_set是一個queryset集合 #反向查詢,需要加上_set
上面正向反向都是基於物件的查詢
2.雙下劃線(__)
雙下劃線(__)之單表條件查詢
models.Book.objects.filter(id__lt=10,id_gt=1)獲取id大於1,小於10的值 and models.Book.objects.filter(id__in=[11,12,13])獲取id在11,12,13中的資料 models.Book.objects.exclude(id__in=[11,12,13]) not in models.Book.objects.exclude(title__contains="ven") #contains類似於like模糊查詢 models.Book.objects.exclude(title__icontains="ven") #icontains大小寫不敏感
models.Book.objects.exclude(title__startwith="p")
models.Book.objects.filter(id__range=[1,10])獲取在1-10之間的資料 ......像:
欄位名__isnull 判斷欄位是否為空
雙下劃線(__)之關聯表條件查詢
一對多,多對多沒有區別
正向查詢 models.Book.objects.filter(title="fsa").values("publish__name") models.Book.objects.filter(publish__name="ffa出版社").values("title") 反向查詢 models.Publish.objects.filter(book__title="XX書",book__id=5).values("name").distinct()
....
關聯查詢,表之間需要有約束,外來鍵,或者ManyToManyField。不能隨便將無關表關聯
3.聚合查詢 aggregate(*args,**kwargs)和分組查詢annotate(*args,**kwargs)(瞭解)
都屬於聚合函式
聚合查詢是在查詢結果集上進行操作,只有一個結果
分組查詢是根據條件對結果進行分組,然後對應每個分組,來進行操作,有多個結果
from django.db.models import Avg,Min,Sum,Max #匯入聚合函式
聚合查詢aggregate:
models.Book.objects.all().aggregate(Avg("price"),Min("price"),Max("price"))
分組查詢annotate:分組條件放在values中
models.Book.objects.values("authors_name").annotate(Sum("price"))#對每個作者分組
4.F和Q查詢(重點)
需求引入:
將所有商品價格增加20
models.Book.objects.all().update(price="price"+20)#錯誤,update不能對某列進行運算,可以直接賦值 解決方法,迴圈每個物件,單個修改,或者迭代,或者使用F
F查詢:用來對某一列值進行操作
from django.db.models import F def data_oper(req): models.Book.objects.all().update(price=F("price")+20)
models.Book.objects.all().update(price=F("title")+'tt')
Q查詢:
前面filter()條件過濾,要麼是單欄位,或者and
Q:可以封裝關鍵字查詢,多關鍵字查詢
from django.db.models import Q def data_oper(req): models.Book.objects.filter(id=3)[0] print(obj) #列印物件的地址(若無__str__) models.Book.objects.filter(Q(id=3)|Q(title="php"))[0] #or print(obj) models.Book.objects.filter(Q(price_gt=50) & (Q(id=3)|Q(title="php")))[0] #and和or print(obj)
models.Book.objects.filter(Q(price_gt=50) & (Q(id=3)|Q(title="php")),color="yellow")[0]
可以把Q物件和關鍵字查詢一起使用,但是一定要把Q物件放在關鍵字查詢前面 結果是列表,包含所有結果
或者可以使用:
q =Q() q.connector = "OR" q.children.append(('id',3)) #注意這裡是元組 q.children.append(('title','php'))
models.Book.objects.filter(q)