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