Q
對象在 Django ORM 中用于構建復雜的查詢條件,特別是當你需要使用邏輯運算符(如 AND、OR、NOT)時。以下是一些使用 Q
對象進行復雜查詢的實際例子。
Q對象使用
模型
假設我們有一個包含員工信息的模型 Employee
:
from django.db import modelsclass Employee(models.Model):name = models.CharField(max_length=100)age = models.IntegerField()department = models.CharField(max_length=100)salary = models.DecimalField(max_digits=10, decimal_places=2)hire_date = models.DateField()def __str__(self):return self.name
1. 使用 Q
對象進行 OR 查詢
獲取所有年齡大于30或工資高于50000的員工:
from django.db.models import Q# 獲取所有年齡大于30或工資高于50000的員工
employees = Employee.objects.filter(Q(age__gt=30) | Q(salary__gt=50000))
for employee in employees:print(employee.name, employee.age, employee.salary)
2. 使用 Q
對象進行 AND 查詢
獲取所有年齡大于30且工資高于50000的員工:
# 獲取所有年齡大于30且工資高于50000的員工
employees = Employee.objects.filter(Q(age__gt=30) & Q(salary__gt=50000))
for employee in employees:print(employee.name, employee.age, employee.salary)
3. 使用 Q
對象進行 NOT 查詢
獲取所有不在 “IT” 部門的員工:
# 獲取所有不在 "IT" 部門的員工
employees = Employee.objects.filter(~Q(department='IT'))
for employee in employees:print(employee.name, employee.department)
4. 組合多個 Q
對象
獲取所有年齡大于30且工資高于50000,或者在 “HR” 部門的員工:
# 獲取所有年齡大于30且工資高于50000,或者在 "HR" 部門的員工
employees = Employee.objects.filter((Q(age__gt=30) & Q(salary__gt=50000)) | Q(department='HR'))
for employee in employees:print(employee.name, employee.age, employee.salary, employee.department)
5. 使用 Q
對象進行復雜的日期查詢
獲取所有在2020年之后入職且工資高于60000的員工:
import datetime# 獲取所有在2020年之后入職且工資高于60000的員工
employees = Employee.objects.filter(Q(hire_date__gt=datetime.date(2020, 1, 1)) & Q(salary__gt=60000))
for employee in employees:print(employee.name, employee.hire_date, employee.salary)
6. 使用 Q
對象進行字段間比較
獲取所有年齡大于工資除以1000的員工:
from django.db.models import F# 獲取所有年齡大于工資除以1000的員工
employees = Employee.objects.filter(Q(age__gt=F('salary') / 1000))
for employee in employees:print(employee.name, employee.age, employee.salary)
7. 使用 Q
對象進行條件更新
將所有年齡大于40或工資低于40000的員工的部門設置為 “Senior”:
# 將所有年齡大于40或工資低于40000的員工的部門設置為 "Senior"
Employee.objects.filter(Q(age__gt=40) | Q(salary__lt=40000)).update(department='Senior')
8. 使用 Q
對象進行復雜的嵌套查詢
獲取所有年齡大于30且工資高于50000,或者年齡小于25且在 “Marketing” 部門的員工:
# 獲取所有年齡大于30且工資高于50000,或者年齡小于25且在 "Marketing" 部門的員工
employees = Employee.objects.filter((Q(age__gt=30) & Q(salary__gt=50000)) | (Q(age__lt=25) & Q(department='Marketing'))
)
for employee in employees:print(employee.name, employee.age, employee.salary, employee.department)
在不使用 Q
對象的情況下,你可以直接在 filter
方法中傳遞多個條件,這些條件默認是 AND 關系。以下是如何實現相同查詢的示例:
不使用 Q
對象的 AND 查詢
模型
假設我們有一個包含員工信息的模型 Employee
:
from django.db import modelsclass Employee(models.Model):name = models.CharField(max_length=100)age = models.IntegerField()department = models.CharField(max_length=100)salary = models.DecimalField(max_digits=10, decimal_places=2)hire_date = models.DateField()def __str__(self):return self.name
獲取所有年齡大于30且工資高于50000的員工:
# 獲取所有年齡大于30且工資高于50000的員工
employees = Employee.objects.filter(age__gt=30, salary__gt=50000)
for employee in employees:print(employee.name, employee.age, employee.salary)
filter
方法接受多個關鍵字參數,每個參數表示一個查詢條件。多個條件之間默認是 AND 關系,因此可以直接使用逗號分隔多個條件。
例子
1. 獲取所有年齡大于30且在 “IT” 部門的員工:
# 獲取所有年齡大于30且在 "IT" 部門的員工
employees = Employee.objects.filter(age__gt=30, department='IT')
for employee in employees:print(employee.name, employee.age, employee.department)
2. 獲取所有工資高于50000且在2020年之后入職的員工:
import datetime# 獲取所有工資高于50000且在2020年之后入職的員工
employees = Employee.objects.filter(salary__gt=50000, hire_date__gt=datetime.date(2020, 1, 1))
for employee in employees:print(employee.name, employee.salary, employee.hire_date)
3. 獲取所有年齡大于30且工資高于50000且在 “HR” 部門的員工:
# 獲取所有年齡大于30且工資高于50000且在 "HR" 部門的員工
employees = Employee.objects.filter(age__gt=30, salary__gt=50000, department='HR')
for employee in employees:print(employee.name, employee.age, employee.salary, employee.department)
Django ORM 也可以輕松實現多個條件的 AND 查詢。但是Q
對象在需要使用 OR 或 NOT 邏輯時特別有用,但對于簡單的 AND 查詢,直接在 filter
方法中傳遞多個條件通常是更簡潔的選擇。