• Django ORM中ExpressionWrapper的用途


    ExpressionWrapper

    在 Django ORM 中,直接在 filter 方法中进行字段间的比较时,不能直接使用算术运算符(如 +、-、*、/)来操作 F 对象,需要使用 ExpressionWrapper 来包装表达式并指定输出字段类型。

    使用Q对象:

    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)
    

    以下是正确的等效写法,不使用 Q 对象:

    from django.db.models import F, ExpressionWrapper, FloatField
    
    # 获取所有年龄大于工资除以1000的员工
    employees = Employee.objects.filter(age__gt=ExpressionWrapper(F('salary') / 1000, output_field=FloatField()))
    for employee in employees:
        print(employee.name, employee.age, employee.salary)
    
    • F('salary') / 1000:使用 F 对象表示字段间的运算。
    • ExpressionWrapper:包装表达式并指定输出字段类型。
    • FloatField:指定输出字段类型为浮点数。

    这种方法避免了使用 Q 对象,并且直接在 filter 方法中进行字段间的比较。
    只比较

    例子

    1. 获取所有工资大于年龄乘以1000的员工:
    # 获取所有工资大于年龄乘以1000的员工
    employees = Employee.objects.filter(salary__gt=ExpressionWrapper(F('age') * 1000, output_field=FloatField()))
    for employee in employees:
        print(employee.name, employee.age, employee.salary)
    
    2. 获取所有入职日期在某个特定日期之后且工资大于某个值的员工:
    import datetime
    
    # 获取所有入职日期在2020年1月1日之后且工资大于50000的员工
    employees = Employee.objects.filter(hire_date__gt=datetime.date(2020, 1, 1), salary__gt=50000)
    for employee in employees:
        print(employee.name, employee.hire_date, employee.salary)
    

    在不使用 Q 对象的情况下,Django ORM 也可以轻松实现字段间的比较和其他复杂查询。Q 对象在需要使用逻辑运算符(如 OR 或 NOT)时特别有用,但对于简单的字段间比较,直接使用 F 对象和 ExpressionWrapper 方法通常是更简洁的选择。

  • 相关阅读:
    官宣!Wayland正式支持基于IntelliJ的IDE
    Python3学习
    【疑难攻关】——XXE漏洞快速入门
    四种经典限流算法的实现思路以及各自的优缺点
    东方博宜11月月赛(A,B,C三组的题解)
    ① 尚品汇的前台开发笔记【尚硅谷】【Vue】
    springboot集成hystrix和feign,解决fallback,fallbackFactory不生效问题
    Electron学习笔记(三)
    接口间调用为什么要用json、fastjson怎么赋值的、fastjson 1.2.83@JSONField映射关系问题
    RKE2 config containerd private registry (rke2配置私有仓库地址)
  • 原文地址:https://blog.csdn.net/daoshen1314/article/details/140360069