批量模糊查询_Django之ORM表高级操作、增删改查、F/Q查询等
目錄
- 一、如何開(kāi)啟自己的測(cè)試腳本?
- 二、對(duì)表數(shù)據(jù)的添加、更新、刪除1.create()變態(tài)操作之批量插入數(shù)據(jù)2.update()3.delete()4.如何查看QuerySet對(duì)象執(zhí)行的sql語(yǔ)句?5.如何配置文件自動(dòng)查看sql語(yǔ)句?
- 三、 單表查詢(xún)13個(gè)操作返回QuerySet對(duì)象的方法有:1.all() 查詢(xún)所有結(jié)果2.filter() 條件匹配3.exclude() 取反4.order_by() 排序5.reverse() 反轉(zhuǎn)6.distinct() 去重特殊的QuerySet:7.values() 獲取指定字段對(duì) 列表套字典8.values_list() 獲取指定字段對(duì)** 列表套字典 列表套元組返回具體對(duì)象的:9.get 直接獲取對(duì)象,不存在就報(bào)錯(cuò)10.first() 取第一個(gè)元素對(duì)象11.last() 取最后一個(gè)元素對(duì)象返回布爾值的方法有:12.exists()返回?cái)?shù)字的方法有:13.count() 統(tǒng)計(jì)數(shù)據(jù)條數(shù)
- 四、神奇的雙下線跨表查詢(xún)
- 五、外鍵字段的增刪改查1.一對(duì)多2.多對(duì)多1.綁定關(guān)系 add2.移除綁定關(guān)系 remove3.修改綁定關(guān)系 set4.清空關(guān)系
- 六、跨表查詢(xún)1.基于對(duì)象的跨表查詢(xún)(子查詢(xún)):2.基于雙下劃線跨表查詢(xún)(鏈表查詢(xún))3.聚合查詢(xún)4.分組查詢(xún)5.F查詢(xún)6.Q查詢(xún)7.Q的高階用法
一、如何開(kāi)啟自己的測(cè)試腳本?
如何只單獨(dú)測(cè)試django中的某一個(gè)py文件如何書(shū)寫(xiě)測(cè)試腳本在任意一個(gè)py文件中書(shū)寫(xiě)以下代碼 應(yīng)用下的tests或者自己新建一個(gè)import osif __name__ == "__main__":os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day53.settings")import djangodjango.setup()這樣就可以直接運(yùn)行你的test.py文件來(lái)運(yùn)行測(cè)試
二、對(duì)表數(shù)據(jù)的添加、更新、刪除
1.create() # 添加 2.update() # 更新 3.delete() # 刪除1.create()
# 對(duì)電影表添加一條數(shù)據(jù) # create() 返回值就是當(dāng)前被創(chuàng)建數(shù)據(jù)的對(duì)象本身 models.Movie.objects.create(title='西游記',price=999.23,publish_time='2016-1-1')# 還可以直接傳日期對(duì)象from datetime import datectime = date.today()models.Movie.objects.create(title='西游記', price=666.23, publish_time=ctime)變態(tài)操作之批量插入數(shù)據(jù)
方式一:
走1000從數(shù)據(jù)庫(kù),非常的慢
def ab_bc(request):# 插入1000條件數(shù)據(jù)for i in range(1,1001):models.Book.objects.create(title='第%s本書(shū)'%i)方式二:調(diào)用bulk_create()方法
插入10000條數(shù)據(jù),走一次數(shù)據(jù)庫(kù)
def ab_bc(request):book_list = []for i in range(1,10001):book_list.append(models.Book(title='新的%s書(shū)'%i))models.Book.objects.bulk_create(book_list) # 批量插入數(shù)據(jù)的方式2.update()
# update() 更新數(shù)據(jù) 返回值是受影響的行數(shù) res = models.Movie.objects.filter(pk=1).update(title='玉女心經(jīng)') print(res) # 1 受影響的條數(shù)3.delete()
# delete() 刪除數(shù)據(jù) 返回值(1, {'app01.Movie': 1}) 受影響的表及行數(shù) res = models.Movie.objects.filter(pk=3).delete() print(res) # (1, {'app01.Movie': 1})4.如何查看QuerySet對(duì)象執(zhí)行的sql語(yǔ)句?
res = models.Movie.objects.filter(pk=3).delete() print(res.query) # 獲取res的sql執(zhí)行語(yǔ)句5.如何配置文件自動(dòng)查看sql語(yǔ)句?
如果你想知道你對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作時(shí),Django內(nèi)部到底是怎么執(zhí)行它的sql語(yǔ)句時(shí)可以加下面的配置來(lái)查看
在Django項(xiàng)目的settings.py文件中,在最后復(fù)制粘貼如下代碼:
LOGGING = {'version': 1,'disable_existing_loggers': False,'handlers': {'console':{'level':'DEBUG','class':'logging.StreamHandler',},},'loggers': {'django.db.backends': {'handlers': ['console'],'propagate': True,'level':'DEBUG',},} }配置好之后,再執(zhí)行任何對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作的語(yǔ)句時(shí),會(huì)自動(dòng)將Django執(zhí)行的sql語(yǔ)句打印到pycharm終端上
三、 單表查詢(xún)13個(gè)操作
返回QuerySet對(duì)象的方法有:all()filter()exclude()order_by()reverse()distinct() 特殊的QuerySet:values() 返回一個(gè)可迭代的字典序列values_list() 返回一個(gè)可迭代的元組序列 返回具體對(duì)象的:get()first()last() 返回布爾值的方法有:exists() 返回?cái)?shù)字的方法有:count()返回QuerySet對(duì)象的方法有:
1.all() 查詢(xún)所有結(jié)果
res = models.Movie.objects.all() print(res)2.filter() 條件匹配
# 獲取電影表中id為1的數(shù)據(jù) # 不存在就返回空,而不是報(bào)錯(cuò)。get(id=1)不存在就直接報(bào)錯(cuò) res = models.Movie.objects.filter(id=1) print(res)3.exclude() 取反
# 獲取id為1之外的數(shù)據(jù) res = models.Movie.objects.exclude(pk=1) print(res)4.order_by() 排序
res = models.Movie.objects.order_by('price') # 默認(rèn)是升序 res = models.Movie.objects.order_by('-price') # 減號(hào)就是降序5.reverse() 反轉(zhuǎn)
res = models.Movie.objects.order_by('price').reverse() # 將次序反轉(zhuǎn)6.distinct() 去重
# 去重:去重的前提 必須是由完全一樣的數(shù)據(jù)的才可以 res = models.Movie.objects.values('title','price').distinct()特殊的QuerySet:
7.values() 獲取指定字段對(duì) 列表套字典
返回一個(gè)可迭代的字典序列
values(*field): 返回一個(gè)ValueQuerySet——一個(gè)特殊的QuerySet,運(yùn)行后得到的并不是一系列model的實(shí)例化對(duì)象,而是一個(gè)可迭代的字典序列
# values() QuerySet對(duì)象 [{},{},{}] 獲取指定字段對(duì)的數(shù)據(jù) # 返回一個(gè)可迭代的字典序列 res = models.Movie.objects.values('title','publish_time')8.values_list() 獲取指定字段對(duì)** 列表套字典 列表套元組
返回一個(gè)可迭代的元組序列
values_list(*field): 它與values()非常相似,它返回的是一個(gè)元組序列,values返回的是一個(gè)字典序列
res = models.Movie.objects.values_list('title','price') print(res)返回具體對(duì)象的:
9.get 直接獲取對(duì)象,不存在就報(bào)錯(cuò)
# get() 直接獲取對(duì)象本身 不推薦使用 當(dāng)查詢(xún)條件不存在的時(shí)候直接報(bào)錯(cuò) res = models.Movie.objects.get(pk=1) print(res)10.first() 取第一個(gè)元素對(duì)象
# first() 數(shù)據(jù)對(duì)象 取第一個(gè)元素對(duì)象 res = models.Movie.objects.filter().first() print(res)11.last() 取最后一個(gè)元素對(duì)象
# last() 數(shù)據(jù)對(duì)象 取最后一個(gè)元素對(duì)象 res = models.Movie.objects.last() print(res)返回布爾值的方法有:
12.exists()
# exists() 返回的是布爾值 判斷前面的對(duì)象是否有數(shù)據(jù) res = models.Movie.objects.filter(pk=1000).exists() # 不存在,Fslse print(res)res = models.Movie.objects.filter(pk=1).exists() # 存在,True返回?cái)?shù)字的方法有:
13.count() 統(tǒng)計(jì)數(shù)據(jù)條數(shù)
# 統(tǒng)計(jì)篩選之后數(shù)據(jù)的條數(shù) res = models.Movie.objects.count() print(res)四、神奇的雙下線跨表查詢(xún)
在python中我們進(jìn)行邏輯判斷會(huì)用到>、<、=、or之類(lèi)的符號(hào),那么在Django進(jìn)行models數(shù)據(jù)操作的時(shí)候,我們表示:雙下劃線
__gt : 大于 __lt : 小于 __gte : 大于等于 __lte : 小于等于 __in : 或 __rang : 在...之間,顧頭也顧尾 __contains :模糊查詢(xún),區(qū)分大小寫(xiě) __icontains :模糊查詢(xún),不區(qū)分大小寫(xiě) __year : 查詢(xún)年份 __month : 查詢(xún)?cè)路?案例:
# 神奇的雙下劃線查詢(xún)# 1.查詢(xún)價(jià)格大于200的電影res = models.Movie.objects.filter(price__gt=200)print(res)# 2.查詢(xún)價(jià)格小于500的電影res = models.Movie.objects.filter(price__lt=500)print(res)# 3.查詢(xún)價(jià)格大于等于876.23的電影res = models.Movie.objects.filter(price__gte=876.23)print(res.query)# 4.查詢(xún)價(jià)格小于等于876.23的電影res = models.Movie.objects.filter(price__lte=500)print(res)# 5.查詢(xún)價(jià)格是123 或666 或876res = models.Movie.objects.filter(price__in=[123,666,876])print(res)# 6.查詢(xún)價(jià)格在200到900之間的電影 顧頭也顧尾res = models.Movie.objects.filter(price__range=(200,900))print(res)# 7.查詢(xún)電影名中包含字母p的電影res = models.Movie.objects.filter(title__contains='p') # 默認(rèn)是區(qū)分大小寫(xiě)res = models.Movie.objects.filter(title__icontains='p') # i忽略大小寫(xiě)# 8.查詢(xún)2014年出版的電影res = models.Movie.objects.filter(publish_time__year=2014)# print(res)# 9.查詢(xún)是1月份出版的電影res = models.Movie.objects.filter(publish_time__month=1)print(res)五、外鍵字段的增刪改查
在1.X版本中默認(rèn)就是級(jí)聯(lián)更新、級(jí)聯(lián)刪除
在2.X版本中需要自己手動(dòng)設(shè)定
1.一對(duì)多
1.增 直接寫(xiě)真實(shí)的表字段
# publish_id是外鍵字段 models.Book.objects.create(title='三國(guó)演義',price=123.23,publish_id=2)2.增 通過(guò)對(duì)象
# Publish 是modles中有關(guān)聯(lián)的表 publish_obj = models.Publish.objects.get(pk=1) models.Book.objects.create(title='大話西游',price=66.66,publish=publish_obj)1.改 直接篩選出來(lái),直接改
models.Book.objects.filter(pk=1).update(publish_id=3)2.改 通過(guò)對(duì)象
# 先獲取出版社表id為4的對(duì)象 publish_obj = models.Publish.objects.get(pk=4) models.Book.objects.filter(pk=1).update(publish=publish_obj)2.多對(duì)多
1.綁定關(guān)系 add
add專(zhuān)門(mén)給第三張關(guān)系表添加數(shù)據(jù)括號(hào)內(nèi)即可以傳數(shù)字也可以傳對(duì)象 并且都支持傳多個(gè)# 1.獲取書(shū)籍對(duì)象 book_obj = models.Book.objects.filter(pk=1).first() # 2.書(shū)籍對(duì)象點(diǎn)‘.’外鍵字段就已經(jīng)跨入第三張表中了。再用add添加綁定關(guān)系 book_obj.authors.add(1,2,3) # 給書(shū)籍綁定一個(gè)主鍵為1,2,3的作者# 獲取對(duì)象author_obj = models.Author.objects.get(pk=1)author_obj1 = models.Author.objects.get(pk=3)# 添加綁定關(guān)系book_obj.authors.add(author_obj)book_obj.authors.add(author_obj,author_obj1)2.移除綁定關(guān)系 remove
remove專(zhuān)門(mén)給第三張關(guān)系表移除數(shù)據(jù)括號(hào)內(nèi)即可以傳數(shù)字也可以傳對(duì)象 并且都支持傳多個(gè)# 按照具體外鍵的值進(jìn)行刪除book_obj = models.Book.objects.filter(pk=1).first()book_obj.authors.remove(2)book_obj.authors.remove(1,3)# 獲取相關(guān)對(duì)象刪除author_obj = models.Author.objects.get(pk=2)author_obj1 = models.Author.objects.get(pk=3)book_obj.authors.remove(author_obj)book_obj.authors.remove(author_obj,author_obj1)3.修改綁定關(guān)系 set
set 修改書(shū)籍與作者的關(guān)系 括號(hào)內(nèi)支持傳數(shù)字和對(duì)象 但是需要是可迭代對(duì)象# authors外鍵字段,Author類(lèi)名 book_obj = models.Book.objects.filter(pk=1).first() book_obj.authors.set((3,)) book_obj.authors.set((2,3))author_obj = models.Author.objects.get(pk=2) author_obj1 = models.Author.objects.get(pk=3) book_obj.authors.set([author_obj,author_obj1]) # 可迭代對(duì)象4.清空關(guān)系
clear() 清空關(guān)系不需要任何的參數(shù)book_obj = models.Book.objects.filter(pk=1).first() book_obj.authors.clear() # 去第三張表中清空書(shū)籍為1的所有數(shù)據(jù)六、跨表查詢(xún)
mysql中跨表查詢(xún)的方式1.子查詢(xún) 將一張表的查詢(xún)結(jié)果當(dāng)做另外一張表的查詢(xún)條件正常解決問(wèn)題的思路 分步操作2.鏈表查詢(xún)inner joinleft joinright joinunion正反向的概念正向跨表查詢(xún)的時(shí)候 外鍵字段是否在當(dāng)前數(shù)據(jù)對(duì)象中 如果在查詢(xún)另外一張關(guān)系表 叫正向反向如果不在叫反向口訣正向查詢(xún)按外鍵字段反向查詢(xún)按表名小寫(xiě)案例:
正向查詢(xún)的時(shí)候 當(dāng)外鍵字段對(duì)應(yīng)的數(shù)據(jù)可以有多個(gè)的時(shí)候需要加.all()否則點(diǎn)外鍵字典即可獲取到對(duì)應(yīng)的數(shù)據(jù)對(duì)象基于對(duì)象的反向查詢(xún) 表名小寫(xiě)是否需要加_set.all()一對(duì)多和多對(duì)多的時(shí)候需要加,查詢(xún)有多個(gè)結(jié)果。 加_set.all()一對(duì)一不需要,查詢(xún)只有一個(gè)結(jié)果 不加1.基于對(duì)象的跨表查詢(xún)(子查詢(xún)):
# 1.查詢(xún)書(shū)籍pk為1的出版社名稱(chēng)book_obj = models.Book.objects.filter(pk=1).first()print(book_obj.publish.name) # 2.查詢(xún)書(shū)籍pk為2的所有作者的姓名book_obj = models.Book.objects.filter(pk=2).first()author_list = book_obj.authors.all()for author_obj in author_list:print(author_obj.name)# 3.查詢(xún)作者pk為1的電話號(hào)碼author_obj = models.Author.objects.filter(pk=1).first()print(author_obj.author_detail.phone)# 4.查詢(xún)出版社名稱(chēng)為東方出版社出版過(guò)的書(shū)籍publish_obj = models.Publish.objects.filter(name='東方出版社').first()print(publish_obj.book_set.all())# 5.查詢(xún)作者為jason寫(xiě)過(guò)的書(shū)author_obj = models.Author.objects.filter(name='jason').first()print(author_obj.book_set.all())# 6.查詢(xún)手機(jī)號(hào)為120的作者姓名author_detail_obj = models.AuthorDetail.objects.filter(phone=120).first()print(author_detail_obj.author.name)2.基于雙下劃線跨表查詢(xún)(鏈表查詢(xún))
只要表之間有關(guān)系 你就可以通過(guò)正向的外鍵字段或者反向的表名小寫(xiě) 連續(xù)跨表操作# 1.查詢(xún)書(shū)籍pk為1的出版社名稱(chēng)# 正向res = models.Book.objects.filter(pk=1).values('publish__name') # 寫(xiě)外鍵字段 就意味著你已經(jīng)在外鍵字段管理的那張表中print(res)# 反向res = models.Publish.objects.filter(book__pk=1) # 拿出版過(guò)pk為1的書(shū)籍對(duì)應(yīng)的出版社res = models.Publish.objects.filter(book__pk=1).values('name')print(res)# 2.查詢(xún)書(shū)籍pk為1的作者姓名和年齡# 正向res = models.Book.objects.filter(pk=1).values('title','authors__name','authors__age')print(res)# 反向res = models.Author.objects.filter(book__pk=1) # 拿出出版過(guò)書(shū)籍pk為1的作者res = models.Author.objects.filter(book__pk=1).values('name','age','book__title')print(res)# 3.查詢(xún)作者是jason的年齡和手機(jī)號(hào)# 正向res = models.Author.objects.filter(name='jason').values('age','author_detail__phone')print(res)# 反向 res = models.AuthorDetail.objects.filter(author__name='jason') # 拿到j(luò)ason的個(gè)人詳情 res = models.AuthorDetail.objects.filter(author__name='jason').values('phone','author__age') print(res)# 4.查詢(xún)書(shū)籍pk為的1的作者的手機(jī)號(hào)# 正向# 只要表之間有關(guān)系 你就可以通過(guò)正向的外鍵字段或者反向的表名小寫(xiě) 連續(xù)跨表操作res = models.Book.objects.filter(pk=1).values('authors__author_detail__phone')print(res)# 反向res = models.AuthorDetail.objects.filter(author__book__pk=1).values('phone')print(res)3.聚合查詢(xún)
需要使用到:aggregate關(guān)鍵字from django.db.models import Max,Min,Avg,Count,Sum # 導(dǎo)入模塊res = models.Book.objects.aggregate(avg_num=Avg('price')) print(res) # 查詢(xún)價(jià)格最貴的書(shū) res = models.Book.objects.aggregate(max_num=Max('price')) print(res) # 全部使用一遍 res = models.Book.objects.aggregate(Avg("price"), Max("price"), Min("price"),Count("pk"),Sum('price')) print(res)4.分組查詢(xún)
需要使用到:annotate關(guān)鍵字# 1.統(tǒng)計(jì)每一本書(shū)的作者個(gè)數(shù)res = models.Book.objects.annotate(author_num=Count('authors')).values('title','author_num')print(res)# 2.統(tǒng)計(jì)出每個(gè)出版社賣(mài)的最便宜的書(shū)的價(jià)格res = models.Publish.objects.annotate(min_price=Min('book__price')).values('name','min_price','book__title')print(res)# 3.統(tǒng)計(jì)不止一個(gè)作者的圖書(shū)res = models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1).values('title')print(res)# 4.查詢(xún)各個(gè)作者出的書(shū)的總價(jià)格res = models.Author.objects.annotate(price_sum=Sum('book__price')).values('name','price_sum')print(res)如何按照表中的某一個(gè)指定字段分組?
res = models.Book.objects.values('price').annotate() 就是以?xún)r(jià)格分組5.F查詢(xún)
在上面所有的例子中,我們構(gòu)造的過(guò)濾器都只是將字段值與某個(gè)我們自己設(shè)定的常量做比較。如果我們要對(duì)兩個(gè)字段的值做比較,那該怎么做呢?
Django 提供 F() 來(lái)做這樣的比較。F() 的實(shí)例可以在查詢(xún)中引用字段,來(lái)比較同一個(gè) model 實(shí)例中兩個(gè)不同字段的值。
簡(jiǎn)而言之:F()查詢(xún)可以動(dòng)態(tài)獲取表字段對(duì)應(yīng)的值
需要導(dǎo)入模塊:from django.db.models import F,Q
案例:
# 1.查詢(xún)庫(kù)存數(shù)大于賣(mài)出數(shù)的書(shū)籍res = models.Book.objects.filter(kucun__gt=F('maichu'))print(res)# 2.將所有書(shū)的價(jià)格提高100res = models.Book.objects.update(price=F('price') + 100)6.Q查詢(xún)
','逗號(hào)隔開(kāi)是and關(guān)系 '|'管道符是or的關(guān)系 '~'是not關(guān)系filter() 等方法中逗號(hào)隔開(kāi)的條件是與的關(guān)系。 如果你需要執(zhí)行更復(fù)雜的查詢(xún)(例如OR語(yǔ)句),你可以使用Q對(duì)象。
示例1:
查詢(xún) 賣(mài)出數(shù)大于100 或者 價(jià)格小于100塊的
from django.db.models import Q models.Product.objects.filter(Q(maichu__gt=100)|Q(price__lt=100))# 1.查詢(xún)書(shū)的名字是python入門(mén)或者價(jià)格是1000的書(shū)籍res = models.Book.objects.filter(title='python入門(mén)',price=1000) # and關(guān)系res = models.Book.objects.filter(Q(title='python入門(mén)'),Q(price=1000)) # 逗號(hào)是and關(guān)系res = models.Book.objects.filter(Q(title='python入門(mén)')|Q(price=1000)) # |是or關(guān)系res = models.Book.objects.filter(~Q(title='python入門(mén)')|Q(price=1000)) # ~是not關(guān)系7.Q的高階用法
res = models.Book.objects.filter('title'='python入門(mén)')q = Q()q.connector = 'or' # q對(duì)象默認(rèn)也是and關(guān)系 可以通過(guò)connector改變orq.children.append(('title','python入門(mén)'))q.children.append(('price',1000))res = models.Book.objects.filter(q)print(res)選擇了IT,必定終身學(xué)習(xí)
總結(jié)
以上是生活随笔為你收集整理的批量模糊查询_Django之ORM表高级操作、增删改查、F/Q查询等的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 三星关闭shell提示_凌晨系统崩溃,低
- 下一篇: python界面散点图_Python数据