python | Django ORM 模糊查詢和查詢操作


模糊查詢常用的操作

Q查詢:

from django.db.models import Q
Q(question__startswith='What')

Q(question__startswith='Who') | Q(question__startswith='What')
This is equivalent to the following SQL WHERE clause:
# 等價於:
WHERE question LIKE 'Who%' OR question LIKE 'What%'
 

Q(question__startswith='Who') | ~Q(pub_date__year=2018)
 
 
Poll.objects.get(
    Q(question__startswith='Who'),
    Q(pub_date=date(2018, 8, 8)) | Q(pub_date=date(2018, 8, 6))
)
... roughly translates into the SQL:
 
SELECT * from polls WHERE question LIKE 'Who%'
    AND (pub_date = '2017-05-02' OR pub_date = '2009-05-06')

大於、大於等於、小於、小於等於:

# __gt 大於>
# __gte 大於等於>=
# __lt 小於<
# __lte 小於等於<=

Student.objects.filter(age__gt=10) # 查詢年齡大於10歲的學生
Student.objects.filter(age__gte=10) # 查詢年齡大於等於10歲的學生
Student.objects.filter(age__lt=10) # 查詢年齡小於10歲的學生
Student.objects.filter(age__lte=10) # 查詢年齡小於等於10歲的學生
  • 特別注意:這里的下划線是雙下划線

不等於/不包含於:

Student.objects.filter().excute(age=10)    # 查詢年齡不為10的學生
Student.objects.filter().excute(age__in=[10, 20])  # 查詢年齡不在 [10, 20] 的學生

數據庫 like操作 模糊查詢常用的操作

# __exact 精確等於 like 'aaa'
# __iexact 精確等於 忽略大小寫 ilike 'aaa'
# __contains 包含 like '%aaa%'
# __icontains 包含,忽略大小寫 ilike '%aaa%',但是對於sqlite來說,contains的作用效果等同於icontains。
# __startswith 以…開頭
# __istartswith 以…開頭 忽略大小寫
# __endswith 以…結尾
# __iendswith 以…結尾,忽略大小寫
# __range 在…范圍內
# __year 日期字段的年份
# __month 日期字段的月份
# __day 日期字段的日


# 用法:
Book.objects.filter(title__exact="python")
#   等價於 title  like  'python'
Book.objects.filter(title__contains="python")
#   等價於 title  like  '%python%'
Book.objects.filter(title__icontains="python")  
# 忽略大小寫 
Book.objects.filter(title__startswith="py")
# 等價於  title like 'py%'
Book.objects.filter(title__endswith="aa")
# 等價於  title like '%aa'

Book.objects.filter(pub_date__year=2012)
# 日期字段的2012年份

Student.objects.filter().excute(age=10) # 查詢年齡不為10的學生
Student.objects.filter().excute(age__in=[10, 20]) # 查詢年齡不在 [10, 20] 的學生

是否為空

User.objects.filter(username__isnull=True) # 查詢用戶名為空的用戶
User.objects.filter(username__isnull=False) # 查詢用戶名不為空的用戶
# a)判等 條件名:exact。
# 例:查詢名字為abc的圖書。
BookInfo.objects.filter(name="abc")  #等同於 BookInfo.objects.filter(name__exact="abc") 名稱嚴格等於 "abc" 的人
BookInfo.objects.filter(name__iexact="abc")  # 名稱為 abc 但是不區分大小寫,可以找到 ABC, Abc, aBC,這些都符合條件

# b)模糊查詢(相當於sql的 like)
# 例:查詢書名包含'傳'的圖書。contains
BookInfo.objects.filter(btitle__contains='')
# 例:查詢書名以'部'結尾的圖書 endswith 開頭:startswith
BookInfo.objects.filter(btitle__endswith='')

# c)空查詢 isnull
# 例:查詢書名不為空的圖書。isnull 
select * from booktest_bookinfo where btitle is not null;
BookInfo.objects.filter(btitle__isnull=False)

# d)范圍查詢 in
# 例:查詢id為1或3或5的圖書。
select * from booktest_bookinfo where id in (1,3,5);
BookInfo.objects.filter(id__in = [1,3,5])

# e)比較查詢 gt(greate than) lt(less  than) gte(equal) 大於等於
# lte 小於等於
# 例:查詢id大於3的圖書。
Select * from booktest_bookinfo where id>3;
BookInfo.objects.filter(id__gt=3)

# f)日期查詢
# 例:查詢1980年發表的圖書。
BookInfo.objects.filter(bpub_date__year=1980)
# 例:查詢1980年1月1日后發表的圖書。
from datetime import date
BookInfo.objects.filter(bpub_date__gt=date(1980,1,1))

# g)range在...范圍內
BookInfo.objects.filter(name__regex="^abc")  # 正則表達式查詢
BookInfo.objects.filter(name__iregex="^abc")  # 正則表達式不區分大小寫

# exclude(返回不滿足條件的數據。)方法示例:
# 例:查詢id不為3的圖書信息。
BookInfo.objects.exclude(id=3)
User.objects.filter().excute(age=10) // 查詢年齡不為10的用戶
User.objects.filter().excute(age__in=[10, 20]) // 查詢年齡不為在 [10, 20] 的用戶

# order_by(對查詢結果進行排序)方法示例:
# 作用:進行查詢結果進行排序。默認是升序,在條件里加“-”表示降序
# 例:查詢所有圖書的信息,按照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')

多表連接查詢:

 class A(models.Model):
    name = models.CharField(u'名稱')
 class B(models.Model):
    aa = models.ForeignKey(A)
 
B.objects.filter(aa__name__contains='searchtitle')
# 查詢B表中外鍵aa所對應的表中字段name包含searchtitle的B表對象。
all():    查詢所有結果
filter(**kwargs):    它包含了與所給篩選條件相匹配的對象
get(**kwargs):    返回與所給篩選條件相匹配的對象,返回結果有且只有一個, 如果符合篩選條件的對象超過一個或者沒有都會拋出錯誤。
exclude(**kwargs):    它包含了與所給篩選條件不匹配的對象
order_by(*field):    對查詢結果排序 用法:order_by(’-price’) DESC 降序
reverse():    對查詢結果反向排序
count():    返回數據庫中匹配查詢(QuerySet)的對象數量。
first():    返回第一條記錄
last():    返回最后一條記錄
exists():    如果QuerySet包含數據,就返回True,否則返回False 相當於limit 1(用途查詢這個表中是否有值)
values(*field):    用法:Book.objects.all.values(‘title’,‘price’) 返回值是<queryset[{‘title’:‘aa’,‘pirce’:12},{}]
values_list(*field):    用法:Book.objects.all.values_list(‘title’,‘price’) 返回值是<queryset[(‘aa’,12),(‘bb’,33)]
distinct():    從返回結果中剔除重復紀錄 用法:Book.objects.all.values(‘title’,‘price’).distinct() 錯誤用法 Book.objects.all.distinct() 因為id不相同,其他相同,無法去重
  1. exclude():
    # exclude(**kwargs)
    # 返回一個新的QuerySet,它包含不滿足給定的查找參數的對象
     
    Student.objects.exclude(age__gt=20, name='lin')#排除所有年齡大於20歲且名字為“lin”的學員集
  2. annotate():

   

annotate(args, *kwargs)
 
# 使用提供的聚合表達式查詢對象。
# 表達式可以是簡單的值、對模型(或任何關聯模型)上的字段的引用或者聚合表達式(平均值、總和等)。
# annotate()的每個參數都是一個annotation,它將添加到返回的QuerySet每個對象中。
# 關鍵字參數指定的Annotation將使用關鍵字作為Annotation 的別名。 匿名參數的別名將基於聚合函數的名稱和模型的字段生成。 只有引用單個字段的聚合表達式才可以使用匿名參數。 其它所有形式都必須用關鍵字參數。
# 例如,如果正在操作一個Blog列表,你可能想知道每個Blog有多少Entry:
>>> from django.db.models import Count
>>> q = Blog.objects.annotate(Count('entry'))
# The name of the first blog
>>> q[0].name
'Blogasaurus'
# The number of entries on the first blog
>>> q[0].entry__count
42
  1. order_by():
order_by(*fields)
 
# 默認情況下,根據模型的Meta類中的ordering屬性對QuerySet中的對象進行排序
Student.objects.filter(school="陽關小學").order_by('-age', 'name')
# 上面的結果將按照age降序排序,然后再按照name升序排序。"-age"前面的負號表示降序順序。 升序是默認的。 要隨機排序,使用"?",如下所示:
Student.objects.order_by('?')
  1. reverse():

# reverse()
# 反向排序QuerySet中返回的元素。 第二次調用reverse()將恢復到原有的排序。
# 如要獲取QuerySet中最后五個元素,可以這樣做:
my_queryset.reverse()[:5]
# 這與Python直接使用負索引有點不一樣。 Django不支持負索引。

  1. distinct():
distinct(*fields)
# 去除查詢結果中重復的行。
# 默認情況下,QuerySet不會去除重復的行。當查詢跨越多張表的數據時,QuerySet可能得到重復的結果,這時候可以使用distinct()進行去重。

 

  1. values():
values(fields, *expressions)
 
# 返回一個包含數據的字典的queryset,而不是模型實例。
 
# 每個字典表示一個對象,鍵對應於模型對象的屬性名稱。如:
 
# 列表中包含的是Student對象
>>> Student.objects.filter(name__startswith='Lin')
<QuerySet [<Student: Lin Student>]>
 
# 列表中包含的是數據字典
>>> Student.objects.filter(name__startswith='Lin').values()
<QuerySet [{'id': 1, 'name': 'Linxiao', 'age': 20}]>
 
# 另外該方法接收可選的位置參數*fields,它指定values()應該限制哪些字段。如果指定字段,每個字典將只包含指定的字段的鍵/值。如果沒有指定字段,每個字典將包含數據庫表中所有字段的鍵和值。如下:
>>> Student.objects.filter(name__startswith='Lin').values()
<QuerySet [{'id': 1, 'name': 'Linxiao', 'age': 20}]>
 
>>> Blog.objects.values('id', 'name')
<QuerySet [{'id': 1, 'name': 'Linxiao'}]>

 

  1. values_list():
values_list(*fields, flat=False)
 
# 與values()類似,只是在迭代時返回的是元組而不是字典。每個元組包含傳遞給values_list()調用的相應字段或表達式的值,因此第一個項目是第一個字段等。 像這樣:
>>> Student.objects.values_list('id', 'name')
<QuerySet [(1, 'Linxiao'), ...]

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM