Django ORM中的Q对象

Q 对象在 Django ORM 中用于构建复杂的查询条件,特别是当你需要使用逻辑运算符(如 AND、OR、NOT)时。以下是一些使用 Q 对象进行复杂查询的实际例子。

Q对象使用

模型

假设我们有一个包含员工信息的模型 Employee

python 复制代码
from django.db import models

class 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的员工:

python 复制代码
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的员工:

python 复制代码
# 获取所有年龄大于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" 部门的员工:

python 复制代码
# 获取所有不在 "IT" 部门的员工
employees = Employee.objects.filter(~Q(department='IT'))
for employee in employees:
    print(employee.name, employee.department)

4. 组合多个 Q 对象

获取所有年龄大于30且工资高于50000,或者在 "HR" 部门的员工:

python 复制代码
# 获取所有年龄大于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的员工:

python 复制代码
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的员工:

python 复制代码
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":

python 复制代码
# 将所有年龄大于40或工资低于40000的员工的部门设置为 "Senior"
Employee.objects.filter(Q(age__gt=40) | Q(salary__lt=40000)).update(department='Senior')

8. 使用 Q 对象进行复杂的嵌套查询

获取所有年龄大于30且工资高于50000,或者年龄小于25且在 "Marketing" 部门的员工:

python 复制代码
# 获取所有年龄大于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

python 复制代码
from django.db import models

class 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的员工:

python 复制代码
# 获取所有年龄大于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" 部门的员工:
python 复制代码
# 获取所有年龄大于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年之后入职的员工:
python 复制代码
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" 部门的员工:
python 复制代码
# 获取所有年龄大于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 方法中传递多个条件通常是更简洁的选择。

相关推荐
noravinsc10 小时前
django admin AttributeError: ‘UserResorce‘ object has no attribute ‘ID‘
数据库·django·sqlite
声声codeGrandMaster15 小时前
django之优化分页功能(利用参数共存及封装来实现)
数据库·后端·python·django
学c真好玩16 小时前
Django创建的应用目录详细解释以及如何操作数据库自动创建表
后端·python·django
沐暖沐16 小时前
Django(快速上手版)
python·django
@_猿来如此1 天前
Django 实现电影推荐系统:从搭建到功能完善(附源码)
数据库·后端·python·django
noravinsc1 天前
django filter 排除字段
后端·python·django
noravinsc1 天前
django admin 设置字段不可编辑
django·filter·count·models
noravinsc1 天前
django filter 日期大于当前日期的
python·django
noravinsc1 天前
django admin 去掉新增 删除
python·django·sqlite
懵逼的小黑子1 天前
解释两个 Django 命令 makemigrations和migrate
数据库·django