Django ORM使用Case和When條件表達式


問題

有這么一個需求,需要根據訂單的創建時間和更新時間排序,要按照最后的操作時間進行排序。

比如,在26分創建了一個訂單a,在27分創建了一個訂單b,然后在28分修改訂單a,又在29分創建了訂單c,那么此時訂單的排序結果,應該是c,a,b。

表中數據(時間是示例,實際是datetime.datetime類型):

ID 訂單號 創建時間 更新時間
1 a 26 28
2 b 27
3 c 29

方案

一開始的想法是根據更新時間排序,然后更新時間為空的,按照創建時間排序。但是這種方式對於沒有更新時間的數據,篩選出來會出現排序混亂的問題。

后來想到可以將兩個字段合成一個字段,這樣就可以對這個字段排序了,但是也有問題,合成一個字段,會出現數據重復,而且也不好篩選和過濾。

在網上搜了搜,看到可以使用SQL的條件表達式,case,when,then。

實現

SQL使用條件表達式,可以判斷update_time是否為空,如果有值,則使用自己的值,如果沒有值則使用create_time,並且可以對結果使用別名,然后根據這個別名來進行排序。這樣排序的時候就會同時根據更新時間和創建時間來排序。

代碼示例

完整代碼示例:

from django.db.models import Case, DateTimeField, F, When

# 查詢所有的數據,只要queryset是Django查詢集即可
queryset = Order.objects.all()

# 
queryset.annotate(
    op_time=Case(
        When(update_time=F("update_time"),             then=F("update_time"),),
        default=F("create_time"),
        output_field=DateTimeField(),
    ),
).order_by("-op_time")

完整的SQL示例:

SELECT
	id,
	create_time,
	update_time,
	(
		CASE update_time
		WHEN update_time THEN
			update_time
		ELSE
			create_time
		END) AS t
FROM
	courtesy_car_order
ORDER BY
	t DESC


免責聲明!

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



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