單表查詢簡單示例python
# 字段 models.DateField(auto_now_add) models.DateField(auto_now) # auto_now 和auto_now_add 都是兩個字段可使用的參數 # auto_now: 每次操做該數據的增刪改查都會自動更新時間 # auto_now_add: 新增數據的時候,會建立時間,後期在作修改的時候,不更新時間
# 新增數據 if __name__=="__main__": os.envron.setdefault('....') import django django.setup() from app01 import models # 新增數據 # 基於create user_obj= models.User.objects.create(name='qzk',age=18,register_time='2019-1-1') # 基於對象的綁定方法 import datetime ctime= datetime.datetime.now() user_obj= models.User(name='qby',age=18,register_time=ctime) user_obj.save() # 修改數據 # 基於對象的綁定方法 user_obj = models.User.objects.filter(name='qzk').first() user_obj.age=19 user_obj.save() # 基於queryset models.User.objdects.filter(name='kevin').update(age=66) # 刪除數據 # 基於queryset models.User.objects.filter(name='qzk').delete() # 基於對象的方法 user_obj=models.User.objects.filter(name='qzk').first() user_obj.delete() # filter() 內能夠放多個限制條件的關鍵參數,可是須要注意的是多個條件之間是and關係 # get() # exclude(**kwargs): 它包含了與說給篩選條件不匹配的對象 # order_by(*field): 對查詢結果排序 默認是升序, 能夠在排序的字段名前面加'-'號,就是降序排列 # reverse(): 對查詢結果反向排序》》》》》前面要現有排序才能反向 # count():返回數據庫中匹配查詢(Queryset)的對象數量 # first(): 返回第一條記錄 res=models.User.objects.all()[0] # 不支持負數索引 # distinct(): 返回結果中剔除重複的記錄,去重的對象必須是徹底相同的 """只要是queryset對象 就能夠無限制的點 queryset方法""" """神奇的雙下劃線查詢""" # 查詢年齡大於44的用戶 res= models.User.objects.filter(age__gt=44) # 查詢年齡小於44的用戶 res= models.User.objects.filter(age__lt=44) # 查詢年齡大於等於44的用戶 res= models.User.objects.filter(age__gte=44) # 查詢年齡小於等於44的用戶 res= models.User.objects.filter(age__lte=44) # 查詢名字中包含n的用戶 res=models.User.objects.filter(name__contains='n') # 在mysql中區分大小寫 res=models.User.objects.filter(name__icontains='n') # 忽略大小寫 # 查詢名字以j開頭的 res=models.User.objects.filter(name__startwith='j') # 查詢名字以n結尾的 res=models.User.objects.filter(name__endwith='j')
class Book(models.Model): name = models.CharField(max_length=32) price = models.DecimalField(max_digits=8,decimal_place=2) publish = models.CharField(max_length=32) author = models.CharField(max_length=32) create_time = models.DateField(null=True) # 配置auto_now_add=True,建立數據記錄的時候會把當前時間添加到數據庫。 # 配置上auto_now=True,每次更新數據記錄的時候會更新該字段。
# 第一種:有返回值,而且就是當前被建立的數據對象 modles.Book.objects.create(name='',price='',publish='',author='',create_time='2019-5-1') # 第二種:先實例化產生對象,而後調用save方法保存 book_obj = models.Book(name='',price='',publish='',author='',create_time='2019-5-1') book_obj.save() # 2.驗證時間格式字段便可以傳字符串也能夠傳時間對象 import datetime ctime = datetime.datetime.now() book = models.Book.objects.create(name='',price='',author='',create_time=ctime)
"""刪除數據""" # 1.刪除書名爲xxx的這本書 queryset方法 res = models.Book.objects.filter(name='').delete() print(res) # 2.刪除書名爲xxx的這本書 queryset方法 res = models.Book.objects.filter(name='').first() res.delete()
# 1.queryset修改 models.Book.objects.filter(name='').update(price='') # 2.對象修改 book = models.Book.objects.filter(name='').first() book.price = 66.66 book.save() # 對象只有保存方法 這樣也能實現修改需求
<1> all(): # 查詢全部結果 <2> filter(**kwargs): # 它包含了與所給篩選條件相匹配的對象 <3> get(**kwargs): # 返回與所給篩選條件相匹配的對象,返回結果有且只有一個,若是符合篩選條件的對象超過一個或者沒有都會拋出錯誤。(源碼就去摟一眼~詮釋爲什麼只能是一個對象) <4> exclude(**kwargs): # 它包含了與所給篩選條件不匹配的對象 <5> order_by(*field): # 對查詢結果排序('-id')/('price') <6> reverse(): # 對查詢結果反向排序 >>>前面要先有排序才能反向 <7> count(): # 返回數據庫中匹配查詢(QuerySet)的對象數量。 <8> first(): # 返回第一條記錄 <9> last(): # 返回最後一條記錄 <10> exists(): # 若是QuerySet包含數據,就返回True,不然返回False <11> values(*field): # 返回一個ValueQuerySet——一個特殊的QuerySet,運行後獲得的並非一系model的實例化對象,而是一個可迭代的字典序列 <12> values_list(*field): # 它與values()很是類似,它返回的是一個元組序列,values返回的是一個字典序列 <13> distinct(): # 從返回結果中剔除重複紀錄 # 必須徹底同樣才能夠去重(意味着帶了id就沒有意義了) res = models.Book.objects.all().values('name').distinct() # 先查一個重複的值再去重
# 查詢名字中包含字母n的用戶 sqlite數據庫演示不出來大小寫的狀況!!! res = models.Author.objects.filter(name__contains='n') res = models.Author.objects.filter(name__icontains='n') print(res) res = models.User.objects.filter(name__icontains='e') # 無視大小寫 print(res) # 查詢名字以j開頭的用戶 res = models.User.objects.filter(name__startswith='j') print(res) # 查詢名字以n結尾的用戶 res = models.User.objects.filter(name__endswith='n') print(res) # 查詢註冊是在2017年的用戶 res = models.User.objects.filter(register_time__year=2017) # sqlite對日期格式不太精準 print(res)
# 價格 大於 小於 大於等於 小於等於 filter(price__gt='90') # 大於 filter(price__lt='90') # 小於 filter(price_gte='90') # 大於等於 filter(price_lte='90') # 小於等於 # 存在與某幾個條件中 filter(price__in=['11','22','33']) # 價格在什麼列表中的價格中 # 在某個範圍內 filter(price__range=[50,90]) # 模糊查詢 filter(title__contains='西') # 標題中包含西字 filter(title__icontains='P') # 不區分大小寫的 包含P的標題 # 以什麼開頭 以什麼結尾 # 按年查詢 filter(create_time__year='2017')
建立圖書管理系統表(給做者表加一張做者詳情表爲了一對一的查詢),詮釋一對一關聯其實就是外健關聯再加一個惟一性約束而已mysql
ForeignKey(unique=Ture) >>> OneToOneField() # 即一對一能夠用ForeignKey來作,可是須要設惟一性約束而且會報警告信息,不建議使用,建議用OneToOneField # 用了OneToOneField和用ForeignKey會自動在字段後面加_id # 用了ManyToMany會自動建立第三張表
# 針對外鍵關聯的字段 兩種添加方式 # 第一種經過publish_id # 第二種經過publish傳出版社對象 # 刪除書籍直接查詢刪除便可,刪除出版社會級聯刪除 # 編輯數據也是兩種對應的方式(對象點的方式(這裏能點publish和publish_id)最後點save(),queryset方式update())
"""前提:先獲取書籍對象,再經過書籍對象點authors來進行書籍做者的增刪改查""" # 1.給書籍新增做者add # 1.add能夠傳做者id,也能夠直接傳做者對象,而且支持傳多個位置參數(不要混着用) # 2.給書籍刪除做者remove # 1.remove一樣能夠傳id,對象,而且支持傳多個位置參數(不要混着用) # 3.直接清空書籍對象全部的做者數據clear()不用傳任何參數 # 4.修改書籍對象所關聯的做者信息set,注意點set括號內必須傳可迭代對象,裏面能夠傳id,對象 """總結:一對多增刪改,多對多add,remove,clear,set"""
# 新增 # 直接寫id models.Book.objects.create(title='紅樓夢',price=66.66,publish_id=1) # 傳數據對象 publish_obj = models.Publish.objects.filter(pk=2).first() models.Book.objects.create(title='三國演義',price=199.99,publish=publish_obj) # 修改 # queryset修改 models.Book.objects.filter(pk=1).update(publish_id=3) publish_obj = models.Publish.objects.filter(pk=2).first() models.Book.objects.filter(pk=1).update(publish=publish_obj) # 對象修改 book_obj = models.Book.objects.filter(pk=1).first() book_obj.publish_id = 3 # 點表中真實存在的字段名 book_obj.save() publish_obj = models.Publish.objects.filter(pk=2).first() book_obj.publish = publish_obj # 點orm中字段名 傳該字段對應的表的數據對象 book_obj.save() # 刪除 # queryset刪除 models.Book.objects.filter(pk=1).delete() models.Publish.objects.filter(pk=1).delete() # 對象刪除 book_obj = models.Book.objects.filter(pk=3).first() book_obj.delete() # 給書籍綁定與做者之間的關係 # 添加關係 add:add支持傳數字或對象,而且均可以傳多個 book_obj = models.Book.objects.filter(pk=3).first() book_obj.authors.add(1) book_obj.authors.add(2,3) author_obj = models.Author.objects.filter(pk=1).first() author_obj1 = models.Author.objects.filter(pk=3).first() book_obj.authors.add(author_obj) book_obj.authors.add(author_obj,author_obj1) # 修改書籍與做者的關係 set() set傳的必須是可迭代對象!!! book_obj = models.Book.objects.filter(pk=3).first() # 能夠傳數字和對象,而且支持傳多個 book_obj.authors.set((1,)) book_obj.authors.set((1,2,3)) author_list = models.Author.objects.all() book_obj = models.Book.objects.filter(pk=3).first() book_obj.authors.set(author_list) # 刪除書籍與做者的綁定關係 # 方法1: book_obj = models.Book.objects.filter(pk=3).first() book_obj.authors.remove(1) book_obj.authors.remove(2,3) # 方法2: author_obj = models.Author.objects.all().first() author_list = models.Author.objects.all() book_obj.authors.remove(author_obj) book_obj.authors.remove(*author_list) # 須要將queryset打散 # 清空 clear() 清空的是你當前這個表記錄對應的綁定關係 # book_obj = models.Book.objects.filter(pk=3).first() # book_obj.authors.clear()
# 正向與方向的概念解釋 # 一對一 # 正向:author---關聯字段在author表裏--->authordetail 按字段 # 反向:authordetail---關聯字段在author表裏--->author 按表名小寫 # 查詢jason做者的手機號 正向查詢 # 查詢地址是 :山東 的做者名字 反向查詢 # 一對多 # 正向:book---關聯字段在book表裏--->publish 按字段 # 反向:publish---關聯字段在book表裏--->book 按表名小寫_set.all() 由於一個出版社對應着多個圖書 # 多對多 # 正向:book---關聯字段在book表裏--->author 按字段 # 反向:author---關聯字段在book表裏--->book 按表名小寫_set.all() 由於一個做者對應着多個圖書 # 連續跨表 # 查詢圖書是三國演義的做者的手機號,先查書,再正向查到做者,在正向查手機號 # 總結:基於對象的查詢都是子查詢,這裏能夠用django配置文件自動打印sql語句的配置作演示
# 正向 # 查詢書籍是三國演義的出版社郵箱 book_obj = models.Book.objects.filter(title='三國演義').first() print(book_obj.publish.email) # 查詢書籍是金梅的做者的姓名 book_obj = models.Book.objects.filter(title='金梅').first() print(book_obj.authors) # app01.Author.None print(book_obj.authors.all()) # 查詢做者爲jason電話號碼 user_obj = models.Author.objects.filter(name='jason').first() print(user_obj.authordetail.phone) # 反向 # 查詢出版社是東方出版社出版的書籍 一對多字段的反向查詢 publish_obj = models.Publish.objects.filter(name='東方出版社').first() print(publish_obj.book_set) # app01.Book.None print(publish_obj.book_set.all()) # 查詢做者jason寫過的全部的書 多對多字段的反向查詢 author_obj = models.Author.objects.filter(name='jason').first() print(author_obj.book_set) # app01.Book.None print(author_obj.book_set.all()) # 查詢做者電話號碼是110的做者姓名 一對一字段的反向查詢 authordetail_obj = models.AuthorDetail.objects.filter(phone=110).first() print(authordetail_obj.author.name)
# 一對一 -連表查詢 -一對一雙下劃線查詢 -正向:按字段,跨表能夠在filter,也能夠在values中 -反向:按表名小寫,跨表能夠在filter,也能夠在values中 # 查詢jason做者的手機號 正向查詢 跨表的話,按字段 # ret=Author.objects.filter(name='jason').values('authordetail__phone') # 以authordetail做爲基表 反向查詢,按表名小寫 跨表的話,用表名小寫 # ret=AuthorDetail.objects.filter(author__name='jason').values('phone') # 查詢jason這個做者的性別和手機號 # 正向 # ret=Author.objects.filter(name='jason').values('sex','authordetail__phone') # 查詢手機號是13888888的做者性別 # ret=Author.objects.filter(authordetail__phone='13888888').values('sex') # ret=AuthorDetail.objects.filter(phone='13888888').values('author__sex') """ 總結 其實你在查詢的時候先把orm查詢語句寫出來,再看用到的條件是否在當前表內,在就直接獲取,不在就按照正向按字段反向按表名來查便可 好比: 1.查詢出版社爲北方出版社的全部圖書的名字和價格 res1 = Publish.objects.filter(name='').values('book__name','book__price') res2 = Book.objects.filter(publish__name='').values('name','price') 2.查詢北方出版社出版的價格大於19的書 res1 = Publish.objects.filter(name='',book__price__gt=19).values('book__name','book__price) """
# 正向 # 查詢書籍爲三國演義的出版社地址 res = models.Book.objects.filter(title='三國演義').values('publish__addr','title') print(res) # 查詢書籍爲金梅的做者的姓名 res = models.Book.objects.filter(title='金梅').values("authors__name",'title') print(res) # 查詢做者爲jason的家鄉 res = models.Author.objects.filter(name='jason').values('authordetail__addr') print(res) # 反向 # 查詢南方出版社出版的書名 res = models.Publish.objects.filter(name='南方出版社').values('book__title') print(res) # 查詢電話號碼爲120的做者姓名 res = models.AuthorDetail.objects.filter(phone=120).values('author__name') print(res) # 查詢做者爲jason的寫的書的名字 res = models.Author.objects.filter(name='jason').values('book__title') print(res) # 查詢書籍爲三國演義的做者的電話號碼 res = models.Book.objects.filter(title='三國演義').values('authors__authordetail__phone') print(res) # 查詢jason做者的手機號 # 正向 res = models.Author.objects.filter(name='jason').values('authordetail__phone') print(res) # 反向 res = models.AuthorDetail.objects.filter(author__name='jason').values('phone') print(res) # 查詢出版社爲東方出版社的全部圖書的名字和價格 # 正向 res = models.Publish.objects.filter(name='東方出版社').values('book__title','book__price') print(res) # 反向 res = models.Book.objects.filter(publish__name='東方出版社').values('title','price') print(res) # 查詢東方出版社出版的價格大於400的書 # 正向 res = models.Publish.objects.filter(name="東方出版社",book__price__gt=400).values('book__title','book__price') print(res) # 反向 res = models.Book.objects.filter(price__gt=400,publish__name='東方出版社').values('title','price') print(res)
# 聚合查詢 aggregate from django.db.models import Max,Min,Count,Sum,Avg # 查詢全部書籍的做者個數 res = models.Book.objects.filter(pk=3).aggregate(count_num=Count('authors')) print(res) # 查詢全部出版社出版的書的平均價格 res = models.Publish.objects.aggregate(avg_price=Avg('book__price')) print(res) # 4498.636 # 統計東方出版社出版的書籍的個數 res = models.Publish.objects.filter(name='東方出版社').aggregate(count_num=Count('book__id')) print(res)
# 分組查詢(group_by) annotate # 統計每一個出版社出版的書的平均價格 res =models.Publish.objects.annotate(avg_price=Avg('book__price')).values('name','avg_price') print(res) # 統計每一本書的做者個數 res = models.Book.objects.annotate(count_num=Count('authors')).values('title','count_num') print(res) # 統計出每一個出版社賣的最便宜的書的價格 res = models.Publish.objects.annotate(min_price=Min('book__price')).values('name','min_price') print(res) # 查詢每一個做者出的書的總價格 res = models.Author.objects.annotate(sum_price=Sum('book__price')).values('name','sum_price') print(res)