1. 程式人生 > >Django 之 models的 F() 和 Q() 函數

Django 之 models的 F() 和 Q() 函數

start sql 更新數據 odi con har class html int

django的模型文件 models.py

#coding: utf8
import datetime
from django.db import models

class Order(models.Model):
    orderid     = models.CharField(max_length=64, unique=True)
    desc        = models.CharField(max_length=512)
    product     = models.CharField(max_length=512, null=True)
    amount      
= models.IntegerField() userid = models.CharField(max_length=512, null=True) create_time = models.DateTimeField(db_index=True)

1. F() ---- 專門取對象中某列值的操作

F()允許Django在未實際鏈接數據的情況下具有對數據庫字段的值的引用。通常情況下我們在更新數據時需要先從數據庫裏將原數據取出後方在內存裏,然後編輯某些屬性,最後提交。例如

order = Order.objects.get(orderid=123456789
) order.amount += 1 order.save()

上述方法生成的sql語句為(可以使用connection.queries查看http://www.cnblogs.com/liuq/p/5946166.html):

UPDATE `core_order` SET ..., `amount` = 22 WHERE `core_order`.`orderid` = ‘123456789‘ # ...表示Order中的其他值,在這裏會重新賦一遍值; 22表示為計算後的結果

其實想生成的sql語句為:

UPDATE `core_order` SET ..., `amount` = `amount` + 1
WHERE `core_order`.`orderid` = ‘123456789‘

這時就可以使用F()方法,代碼如下:

1 from django.db.models import F
2 from core.models import Order
3  
4 order = Order.objects.get(orderid=‘123456789‘)
5 order.amount = F(‘amount‘) - 1
6 order.save()

查看生成的sql:

UPDATE `core_order` SET ..., `amount` = `core_order`.`amount` - 1 WHERE `core_order`.`orderid` = ‘123456789‘ # 和預計的一樣

當Django程序中出現F()時,Django會使用SQL語句的方式取代標準的Python操作。

上述代碼中不管 order.amount 的值是什麽,Python都不曾獲取過其值,python做的唯一的事情就是通過Django的F()函數創建了一條SQL語句然後執行而已。

需要註意的是在使用上述方法更新過數據之後需要重新加載數據來使數據庫中的值與程序中的值對應

order= Order.objects.get(pk=order.pk)

或者使用更加簡單的方法:

order.refresh_from_db() 這裏只做引子,詳細參考如下: 博客:http://www.tuicool.com/articles/u6FBRz 官網:https://docs.djangoproject.com/en/1.10/ref/models/expressions/

2. Q() ---- 對對象的復雜查詢

Q對象(django.db.models.Q)可以對關鍵字參數進行封裝,從而更好地應用多個查詢。可以組合使用 &(and),|(or),~(not)操作符,當一個操作符是用於兩個Q的對象,它產生一個新的Q對象。
Order.objects.get(
    Q(desc__startswith=‘Who‘),
    Q(create_time=date(2016, 10, 2)) | Q(create_time=date(2016, 10, 6))
)

轉換成sql語句,大致如下:

SELECT * from core_order WHERE desc LIKE ‘Who%‘ AND (create_time = ‘2016-10-02‘ OR create_time = ‘2016-10-06‘)

Q對象可以與關鍵字參數查詢一起使用,不過一定要把Q對象放在關鍵字參數查詢的前面

正確寫法:

Order.objects.get(
    Q(create_time=date(2016, 10, 2)) | Q(create_time=date(2016, 10, 6))
    desc__startswith=‘Who‘,
)

錯誤寫法:

Order.objects.get(
    desc__startswith=‘Who‘,
    Q(create_time=date(2016, 10, 2)) | Q(create_time=date(2016, 10, 6))
)

詳細內容可查看下面地址:

博客:http://www.cnblogs.com/linjiqin/p/3817814.html 官網:https://docs.djangoproject.com/en/1.10/topics/db/queries/#complex-lookups-with-q

Django 之 models的 F() 和 Q() 函數