1. 程式人生 > >西遊之路——python全棧——django中orm的使用(2) python---django中orm的使用(1)

西遊之路——python全棧——django中orm的使用(2) python---django中orm的使用(1)

目錄

 

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()
6 price=models.DecimalField(max_digits=5,decimal_places=2,default=10) 7 def __str__(self): 8 return self.title 9 10 Book(多)
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_name
12 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)
複製程式碼