1、F與Q查詢
F查詢
F查詢的應用場景主要是當你想要查詢字段須要與數據庫中的另一個字段進行比較的時候,基於咱們前面所學的知識點沒法完成,那就須要用到F查詢。
git
F的導入
from django.db.models import F,Q
F查詢的使用
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
class Product(models.Model): name = models.CharField(max_length=32) price = models.DecimalField(max_digits=8, decimal_places=2) maichu = models.IntegerField() kucun = models.IntegerField() def __str__(self): return '這是商品:%s'%self.name
基於models表作的幾個F查詢的練習數據庫
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
#查詢賣出數大於500的商品 res = models.Product.objects.filter(maichu__gt=500) print(res) from django.db.models import F,Q # 查詢賣出數大於庫存數的商品 res = models.Product.objects.filter(maichu__gt=F('kucun')) print(res) #查詢賣出數小於庫存數 res = models.Product.objects.filter(maichu__lt=F('kucun')) print(res) #將全部的商品的價格提升100塊 res = models.Product.objects.update(price=F('price')+100) print(res)
其實經過上面的練習,你也發現了F查詢的本質其實就是給你一個字符串形式的字段,你能夠直接拿出這個字段在數據庫中存儲的值,而後能夠對拿到的這個值進行操做。和其餘字段值的比較,將當前字段的值所有加100等...可是,若是想讓你給當前的字段加一個後綴,怎麼實現呢?這還不簡單,來,看我秀!django
#將全部的商品後面都加上一個爆款 models.Product.objects.update(name=F('name')+'爆款')
而後一執行,哎呀,怎麼回事,小老弟,怎麼會這樣併發
再次嘗試app
bug緣由以下ide
第一步:atom
第二步:spa
麼有刷新數據庫,直接執行了正確的操做,就會變成上面的結果👆👆👆code
最終正確的方案,雖然沒什麼驚喜了,可是仍是來low一眼吧🤦🤦🤦對象
Q查詢
F主要是用於查詢數據庫中的另一個字段,那麼你有沒有發現,咱們每次查詢他的filter裏面的參數都是and的關係,可是咱們又不想每次都是and,就算是鹹魚久了還要翻身呢吧,那咱們實際查詢的時候改變字段的關係就得用到這個新的知識點了,Q查詢
Q查詢的一些小練習
or
not
Q對象補充(*****)
當外界獲取用戶那邊輸入的是一個字符串,能夠獲取數據庫裏面的值
#Q對象的補充(****) from django.db.models import F,Q q=Q() q.connector='or' #經過這個參數能夠將q對象默認的and關係變成or q.children.append(('price',199)) #外界傳來的是一個字符串的形式 q.children.append(('name','絲襪爆款')) res = models.Product.objects.filter(q) #支持直接將q丟進去 print(res)
2、事務
1.事務的四大特性:
Atomic(原子性):事務中包含的操做被看作一個邏輯單元,這個邏輯單元中的操做要麼所有成 功,要麼所有失敗。
Consistency(一致性):事務完成時,數據必須處於一致狀態,數據的完整性約束沒有被破壞,事務在執行過程當中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務歷來沒 有執行過同樣。
Isolation(隔離性):事務容許多個用戶對同一個數據進行併發訪問,而不破壞數據的正確性 和完整性。同時,並行事務的修改必須與其餘並行事務的修改相互獨立。
Durability(持久性):事務結束後,事務處理的結果必須可以獲得固化。
2.django事務的使用
在數據庫中使用事務的時候,咱們必須使用start開啓事務,可是在django中支持直接開始事務,事務的開啓用的是with
from django.db import transaction
事務的開啓
from django.db import transaction with transaction.atomic(): #再這裏寫數據庫操做
from django.db import transaction from django.db.models import F with transaction.atomic(): models.Product.objects.filter(id=1).update(kucun=F('kucun')-1) models.Product.objects.filter(id=1).update(maichu=F('maichu')+1)
3、自定義字段
由於django是不支持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): return 'char(%s)'%self.max_length class User(models.Model): name=models.CharField(max_length=32) password=MyCharField(max_length=32)
4、only與defer
only與defer二者是相反的,拿到的都是一個對象,對於only來講,若是後面你要查詢的字段是指定的字段的話,就會只走一次數據庫,其餘字段就會走四次數據庫,可是defer是與他們恰好相反,查當前指定字段的話就會走四次數據庫,其餘數據就會只走一次數據庫
# only與defer 拿到的是一個對象 二者是相反的 res = models.Product.objects.values('name') res1 = models.Product.objects.only('name') res2 = models.Product.objects.defer('name') for i in res: print(i.name)
5、choices字段(**)
主要是用於存儲信息的時候,選擇的不一樣數據對應到不一樣的內容,而後給用戶看的是內容,數據庫中存的是數字
choices字段 #涉及到選擇選擇相關的,都有的是choices字段 class User(models.Model): name=models.CharField(max_length=32) password=MyCharField(max_length=32) choices=((1,'重點大學'),(2,'普通本科'),(3,'專科'),(4,'其餘'),(),()) education = models.IntergeField(choices=choices) #有這個參數 user_obj.education #拿到的是數字 user_obj.get_education_display() #固定用法,獲取choices字段對應的註釋