python3開發進階-Django框架中的ORM的常用操作的補充(F查詢和Q查詢,事務)
閱讀目錄
- F查詢和Q查詢
- 事務
一、F查詢和Q查詢
1、F查詢
查詢前的準備
class Product(models.Model): name = models.CharField(max_length=32) price = models.DecimalField(max_digits=10, decimal_places=2) # 庫存數 inventory = models.IntegerField() # 賣出數 sale = models.IntegerField()app下的modelsdef __str__(self): return "{}:{}:{}:{}".format(self.name, self.price, self.inventory, self.sale)
INSERT INTO app01_product (id, name, price, inventory, sale) VALUES (1, ‘跟大娃變大‘, 239, 1000, 10); INSERT INTO app01_product (id, name, price, inventory, sale) VALUES (2, ‘跟二娃學吹牛逼‘SQL數據名稱:main_app01_product, 20150, 60, 60); INSERT INTO app01_product (id, name, price, inventory, sale) VALUES (3, ‘跟三娃學喊麥‘, 50150, 100, 0); INSERT INTO app01_product (id, name, price, inventory, sale) VALUES (4, ‘跟四娃學詩歌‘, 159, 50, 10000); INSERT INTO app01_product (id, name, price, inventory, sale) VALUES (5, ‘跟五娃學樹新風‘, 155, 100, 200); INSERTINTO app01_product (id, name, price, inventory, sale) VALUES (6, ‘跟六娃學噴口水‘, 152, 200, 1);
在上面所有的例子中,我們構造的過濾器都只是將字段值與某個常量做比較。如果我們要對兩個字段的值做比較,那該怎麽做呢?
Django 提供 F() 來做這樣的比較。F() 的實例可以在查詢中引用字段,來比較同一個 model 實例中兩個不同字段的值。
示例1:
查詢賣出數大於庫存數的商品
from django.db.models import F models.Product.objects.filter(sale__gt=F(‘inventory‘))
Django 支持 F() 對象之間以及 F() 對象和常數之間的加減乘除和取模的操作。
models.Product.objects.filter(sale__lt=F(‘sale‘)*2)
修改操作也可以使用F函數,比如將每一本書的價格提高30元
models.Product.objects.update(price=F("price")+30)
註意:update修改字段和對象,屬性修改字段的區別:
1、對象.屬性方法會更新所有字段
2、update方法只會更新你修改的那個字段
引申:
如果要修改char字段咋辦?
如:把所有書名後面加上(第一版)
from django.db.models.functions import Concat from django.db.models import Value models.Product.objects.update(title=Concat(F("title"), Value("("), Value("第一版"), Value(")")))
2、Q查詢
1、多個查詢條件做 交集 並集 取反操作時
2、如果Q查詢和關鍵字查詢同時存在時,Q查詢要放在關鍵字查詢的前面
filter() 等方法中的關鍵字參數查詢都是一起進行“AND” 的。 如果你需要執行更復雜的查詢(例如OR語句),你可以使用Q對象。
示例1:
查詢賣出數大於100或者價格小於100
models.Product.objects.filter(Q(sale__gt=100)|Q(sale__lt=100))
你可以組合& 和| 操作符以及使用括號進行分組來編寫任意復雜的Q 對象。同時,Q 對象可以使用~ 操作符取反,這允許組合正常的查詢和取反(NOT) 查詢。
示例:查詢庫存數是100 並且 賣出數不是0 的商品
models.Product.objects.filter(Q(inventory=100) & ~Q(sale=0))
查詢函數可以混合使用Q 對象和關鍵字參數。所有提供給查詢函數的參數(關鍵字參數或Q 對象)都將"AND”在一起。但是,如果出現Q 對象,它必須位於所有關鍵字參數的前面。
例如:查詢商品名包含噴口水,並且庫存數大於60
models.Product.objects.filter(Q(inventory__gt=60), name__icontains="噴口水")
二、事務
1、什麽是事務?
數據的原子性、隔離性、持久性、一致性
class Product(models.Model): name = models.CharField(max_length=32) price = models.DecimalField(max_digits=10, decimal_places=2) # 庫存數 inventory = models.IntegerField() # 賣出數 sale= models.IntegerField() def __str__(self): return "{}:{}:{}:{}".format(self.name, self.price, self.inventory, self.sale) class Order(models.Model): num = models.CharField(max_length=64) product = models.ForeignKey(to="Product") count = models.IntegerField()models中的類
INSERT INTO app01_product (id, name, price, inventory, sale) VALUES (1, ‘跟大娃變大‘, 239, 1000, 10); INSERT INTO app01_product (id, name, price, inventory, sale) VALUES (2, ‘跟二娃學吹牛逼‘, 20150, 60, 60); INSERT INTO app01_product (id, name, price, inventory, sale) VALUES (3, ‘跟三娃學喊麥‘, 50150, 100, 0); INSERT INTO app01_product (id, name, price, inventory, sale) VALUES (4, ‘跟四娃學詩歌‘, 159, 50, 10000); INSERT INTO app01_product (id, name, price, inventory, sale) VALUES (5, ‘跟五娃學樹新風‘, 155, 100, 200); INSERT INTO app01_product (id, name, price, inventory, sale) VALUES (6, ‘跟六娃學噴口水‘, 152, 200, 1);SQL數據main_app01_product
import os if __name__ == ‘__main__‘: os.environ.setdefault("DJANGO_SETTINGS_MODULE", "BMS.settings") import django django.setup() import datetime from app01 import models try:
from django.db.models import F from django.db import transaction
#買一本書
#在數據庫層面要做到的事兒
#1、創建一條訂單數據
#2、去產品表 將賣出數+1,庫存數-1 with transaction.atomic(): #開啟事務處理
#創建一條訂單數據
models.Order.objects.create(num=‘123456789‘,product_id=1,count=1)
#去產品表 將賣出數+1,庫存數-1(報錯)
models.Product.objects.get(id=1).update(inventory=F(‘inventory‘)-1,sale=F(‘sale‘)+1)
#能執行成功
#models.Product.objects.filter(id=1).update(inventory=F(‘inventory‘-1,sale=F(‘sale‘)+1))
except Exception as e:
print(e)
# 不開啟事務
# try:
# # 創建一條訂單數據
# models.Order.objects.create(num="123456789", product_id=1, count=1)
# # 去產品表 將賣出數+1, 庫存數-1
# models.Product.objects.get(id=1).update(kucun=F("kucun") - 1, maichu=F("maichu") + 1)
# except Exception as e:
# print(e)
python3開發進階-Django框架中的ORM的常用操作的補充(F查詢和Q查詢,事務)