在 Django QuerySets API 中, F() 用於直接在數據庫中引用模型的值。假設你有一個帶有price
的 Product 模型, 你希望爲所有的Product的價格上漲20%.
一個可以實現在解決方案:
Python
products = Product.objects.all() for product in products: product.price *= 1.2 product.save()
相反, 你可以在單個查詢中更新price.
Python
from django.db.models import F Product.objects.update(price=F('price') * 1.2)
你也可以對單個對象執行這個操作:
Python
product = Product.objects.get(pk=5009) product.price = F('price') * 1.2 product.save()
要注意, 保存模型後,
F()
對象依然存在.
Python
product.price # price = Decimal('10.00') product.price = F('price') + 1 product.save() # price = Decimal('11.00') product.name = 'What the F()' product.save() # price = Decimal('12.00')
所以, 在更新這樣的字段後, product.price
實際上保存的是django.db.models.expressions.CombinedExpression
實例, 而不是實際結果。
如果要立即訪問結果:
Python
product.price = F('price') + 1 product.save() print(product.price) # <CombinedExpression: F(price) + Value(1)> product.refresh_from_db() print(product.price) # Decimal('13.00')
你可以使用F()
實現annotate功能:
Python
from django.db.models import ExpressionWrapper, DecimalField Product.objects.all().annotate( value_in_stock=ExpressionWrapper( F('price') * F('stock'), output_field=DecimalField() ) )
由於price是DecimalField, 而stock是IntegerField,我們需要將表達式包裝在ExpressionWrapper
中.
也可以用來過濾數據:
Python
Product.objects.filter(stock__gte=F('ordered'))