表查詢
基於django settings源碼實現自己的項目
配置文件的可插拔式設計
dir()
importlib
反射
單表查詢
只要是queryset對象 就可以無限制的點擊queryset對象的方法
13條
1.all() # 查所有
2.filter() # 根據條件過濾 多個條件之間是and關系
3.get() # 直接獲取數據對象 查詢條件不存在直接報錯
4.first() # 取queryset的第一個數據對象
5.last() # 取queryset的最后一個數據對象
6.exclude() # 除此之外
7.values() # queryset 類似於列表套字典
8.values_list() # queryset 類似於列表套元組
9.count() # 統計數據個數
10.distinct() # 一定要是完全一樣的數據才能去重
11.order_by() # 排序 默認是升序 加負號就變成降序
12.reverse() # 反轉 排序之后才能反轉
13.exists() # 判斷queryset是否有值 結果是個布爾值
神奇的雙下線的查詢
price__gt
price__lt
price__gte
price__lte
price__in=[100,200,300]
price__range=(200,800)
title__contains 包含 模糊匹配
title__icontains 忽略大小寫
publish_date__year 只針對年份
publish_date__month 只針對月份
title__startswith
title__endswith
多表查詢
前期表准備
圖書管理系統
一對多
多對多
一對一
外鍵字段的增刪改查
一對多字段
create(publish_id=1)
create(publish=publish_obj)
update(publish_id=2)
update(publish=publish_obj1)
models.Publish.objects.filter(pk=2).delete()
# orm外鍵默認是級聯更新 級聯刪除的
多對多字段
# 朝第三張關系表中添加數據
book_obj.authors.add(1)
book_obj.authors.add(1,2,3,4)
book_obj.authors.add(author_obj)
book_obj.authors.add(author_obj,author_obj1,author_obj2)
# 朝第三張表修改數據
book_obj.authors.set((1,))
book_obj.authors.set((1,2,3))
book_obj.authors.set((author_obj,))
book_obj.authors.set((author_obj,author_obj1))
# 朝第三張表刪除關系
book_obj.authors.remove(1)
book_obj.authors.remove(1,2,3,4)
book_obj.authors.remove(author_obj)
book_obj.authors.remove(author_obj,author_obj1)
# 朝第三張表清空當前書籍對象所有的記錄
book_obj.authors.clear()
跨表查詢
正反向的概念:
外鍵字段在誰那兒 誰就是正向
沒有外鍵字段的 就是反向
口訣:
正向查詢按字段
反向查詢按表名小寫
基於對象 # 子查詢
"""
步驟都是先獲取一個數據對象
然后利用對象點點點的方式查到鎖對應的數據
"""
# 正向
book_obj.publish.name
book_obj.authors.all()
author_obj.author_detail.addr
"""
外鍵字段所對應的數據 如果是單個 不需要加all
如果是多個 需要加all()
"""
# 反向
publish_obj.book_set.all()
author_obj.book_set.all()
author_detail_obj.author.name
"""
反向查詢 數據如果是多個
那么需要 表名小寫_set.all()
如果是一個 直接表名小寫即可
"""
基於雙下划綫 # 連表查詢
"""
left join
right join
inner join
union
"""
# 正向
models.Book.objects.filter(title='python').values('publish__name')
# 寫外鍵字段publish之后 就會跨到publish表中 你想要該表的哪個字段對應的數據 就加__字段名獲取
models.Book.objecst.filter(pk=1).values('authors__name')
models.Author.objects.filter(name='jason').values('author_detail__addr')
models.Publish.objects.filter(pk=1).values('book__title')
models.authors.objects.filter(pk=1).values('book__title')
models.AuthorDetail.objects.filter(pk=1).values('author__name')
# 反向
models.Publish.objects.filter(book__title='python').values('name')
"""查詢書籍id為1 的作者的 手機號"""
models.Book.objects.filter(pk=1).values('authors__author_detail__phone')
聚合查詢
聚合函數
from django.db.models import Max,Min,Sum,Count,Avg
分組查詢
F與Q查詢
orm中常見字段
AutoField(primary_key=True)
CharField(max_length=32) varchar(32)
IntegerField() int
BigIntegerField() long
DateField()
auto_now:每次修改數據的時候 都會更新該字段
auto_now_add:只在創建數據的時候 才會自動將創建時間添加 后續不會再自動修改了
DecimalField()
BooleanField(Field)
- 布爾值類型
該字段在存儲數據的時候 你只需要傳布爾值即可
對應到數據庫中 會變成0/1
TextField(Field)
- 文本類型
存大段文本
EmailField(CharField) varchar(...)
FileField(Field)
- 字符串,路徑保存在數據庫,文件上傳到指定目錄
- 參數:
upload_to = "" 上傳文件的保存路徑
storage = None 存儲組件,默認django.core.files.storage.FileSystemStorage
DecimalField(Field)
- 10進制小數
- 參數:
max_digits,小數總長度
decimal_places,小數位長度
自定義char字段
# 自定義char類型字段
class MyCharField(models.Field):
def __init__(self,max_length,*args,**kwargs):
self.max_length = max_length
super().__init__(max_length=max_length,*args,**kwargs)
def db_type(self, connection):
return 'char(%s)'%self.max_length
如果你使用的是django2.X版本 你在建數據庫表關系的時候
你需要手動指定兩個參數
(你要手動告訴django 級聯更新 級聯刪除 是否建外鍵約束)
on_delete
db_constraint
!!!!!!!!!!碎片化學習!!!!!!!
查詢優化(面試比較喜歡問的)
only與defer
select_related和prefetch_related
django orm中的事務操作
ACID
原子性
一致性
隔離性
持久性
commit
rollback
要么同時成功要么同時失敗
from django.db import transaction
with transaction.atomic():
# 在該代碼塊中所寫的orm語句 同屬於一個事務
# 縮進出來之后自動結束
聚合查詢(aggregate)
from django.db.models import Max,Min,Count,Avg,Sum #查詢總和,平均,最大,最小
res = models.Book.objects.aggregate(Sum('price'))
res1 = models.Book.objects.aggregate(Avg('price'))
res2 = models.Book.objects.aggregate(Count('price'))
res3 = models.Book.objects.aggregate(Max('price'))
res4 = models.Book.objects.aggregate(Min('price'))
res5 = models.Book.objects.aggregate(Max('price'),Min('price'),Count('pk'),Avg('price'),Sum('price')) #也可以放在一個里面寫
分組查詢 (annotate)
1.統計每一本書的作者個數
from django.db.models import Max, Min, Count, Avg, Sum
res = models.Book.objects.annotate(author_num = Count('authors')).values('author_num','title')
#book表根據authors分組求和,author_num是取的別名,values是控制台打印的值
2.統計每個出版社賣的最便宜的書的價格
res = models.Publish.objects.annotate(mmp = Min('book__price')).values('name','mmp')
3.統計不止一個作者的圖書
res = models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1)
4.查詢每個作者出的書的總價格
res = models.Author.objects.annotate(sp=Sum('book__price')).values('name','sp')
F查詢與Q查詢
F查詢的本質就是從數據庫中獲取某個字段的值,之前查詢等號后面的條件都是我們人為輸入的,現在變成了需要從數據庫中獲取數據放在等號后面
查詢庫存量大於賣出量的書籍
from django.db.models import F
res = models.Book.objects.filter(kucun__gt=F('maichu')) #kucun和maichu都是Book表的字段
將書籍庫存數全部增加1000
models.Book.objects.update(kucun=F('kucun')+1000)
把所有書名后面加上'新款'
from django.db.models.functions import Concat
from django.db.models import Value
ret3 = models.Book.objects.update(title=Concat(F('title'), Value('新款')))
models.Book.objects.update(title = F('title')+'新款') # 不能這么寫
Q查詢 (filter里面條件都是與,Q支持與或非)
查詢書籍名稱是三國演義或者價格是444
from django.db.models import Q
res = models.Book.objects.filter(title='三國演義',price=444.44) # filter只支持and關系
res1 = models.Book.objects.filter(Q(title='三國演義'),Q(price=444)) # 如果用逗號 那么還是and關系
res2 = models.Book.objects.filter(Q(title='三國演義')|Q(price=444)) #或者關系
res3 = models.Book.objects.filter(~Q(title='三國演義')|Q(price=444)) #查詢除了title是三國演義,或者價格是444的書籍
Q的高級用法
from django.db.models import Q
q = Q()
q.connector = 'or' # 修改查詢條件的關系 默認是and
q.children.append(('title__contains','三國演義')) # 往列表中添加篩選條件
q.children.append(('price__gt',444)) # 往列表中添加篩選條件
res = models.Book.objects.filter(q) # filter支持你直接傳q對象 但是默認還是and關系
print(res)