1. 程式人生 > >python3開發進階-Django框架中的ORM的常用操作的補充(F查詢和Q查詢,事務)

python3開發進階-Django框架中的ORM的常用操作的補充(F查詢和Q查詢,事務)

這樣的 env atomic 實例 In git 必須 TE setup

閱讀目錄

  1. F查詢和Q查詢
  2. 事務

一、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()


    
def __str__(self): return "{}:{}:{}:{}".format(self.name, self.price, self.inventory, self.sale)
app下的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

在上面所有的例子中,我們構造的過濾器都只是將字段值與某個常量做比較。如果我們要對兩個字段的值做比較,那該怎麽做呢?

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查詢,事務)