76.Python中F表達式詳解


F表達式是用來優化ORM操作數據庫的。

舉個例子:我們做口罩的公司要將所有員工的薪水增加2000元,如果按照正常的流程,應該是先從數據庫中提取所有的員工的工資到Python內存中,然后使用Python代碼在員工工資的基礎上增加2000元,最后在保存到數據庫中,這里面涉及到的流程就是,首先從數據庫中提取數據到Python內存中,然后在Python內存中做完運算,之后再保存到數據庫中。示例代碼如下:
from django.db.models import F
from django.http import HttpResponse
from .models import BookOrder


# F表達式的用法詳解:F表達式並不會真正的到數據庫中查詢數據,僅僅只是起到一個標識的作用,告訴sql語句目前的值為多少。
def index2(request):
# 1. 同樣也可以先提取出所有的訂單,並且將訂單中的price減去10元,之后保存到數據庫中。
    books = BookOrder.objects.all()
    for book in books:
        book.price -= 10
        book.save()
    print(connection.queries[-1])
    # {
    #     'sql': "UPDATE `book_order` SET `book_id` = 1, `price` = 79.0e0, `time` = '2020-02-04 01:22:43.534747' WHERE `book_order`.`id` = 7",
    #     'time': '0.047'}

    return HttpResponse("index2")
如果我們使用F表達式,就可以優化這個流程,他可以不需要先把數據從數據庫中提取出來,計算完成后,再保存回去 。他可以直接執行SQL語句,就將員工工資增加2000元。示例代碼如下:
from django.db.models import F
from django.http import HttpResponse
from .models import BookOrder


# F表達式的用法詳解:F表達式並不會真正的到數據庫中查詢數據,僅僅只是起到一個標識的作用,告訴sql語句目前的值為多少。
def index2(request):
# 2. 將bookorder表中預定價格降低10元
    # 注意:調用的是update()方法,可以直接在數據庫層面直接調用F表達式更改數據庫中的數據信息
    BookOrder.objects.update(price=F('price')-10)
    # 因為connection.queries返回的是一個包含多個字典的列表,並且只有最后一個字典中的sql語句才是我們代碼中執行的sql語句
    print(connection.queries[-1])
    # {'sql': 'UPDATE `book_order` SET `price` = (`book_order`.`price` - 10)', 'time': '0.125'}
	return HttpResponse('indes2')
其中,models.py文件中模型的定義為:
from django.db import models


# 定義圖書模型
class Book(models.Model):
    name = models.CharField(max_length=100, unique=True)
    pages = models.IntegerField()
    price = models.FloatField()
    rating = models.FloatField()
    author = models.ForeignKey('Author', on_delete=models.CASCADE)
    publisher = models.ForeignKey('Publisher', on_delete=models.CASCADE)

    class Meta:
        db_table = 'book'

    def __str__(self):
        return "(書名:%s,頁數:%s,價格:%s,打折:%s,作者:%s,出版社:%s)" % (self.name, self.pages, self.price, self.rating, self.author, self.publisher)


# 定義預定圖書的模型
class BookOrder(models.Model):
    book = models.ForeignKey('Book', on_delete=models.CASCADE)
    price = models.FloatField()
    time = models.DateTimeField(auto_now_add=True, null=True)

    class Meta:
        db_table = 'book_order'
F表達式並不會馬上從數據庫中獲取數據,而是在生成sql語句的時候,動態的獲取傳給F表達式的值。在執行操作之前,數據庫中的數據信息如下:

在這里插入圖片描述

執行操作之后,數據庫中信息為:

在這里插入圖片描述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM