Django 如何使用F()表达式

Django 如何使用F()表达式

在本教程中,我们将学习关于查询表达式、F表达式以及如何在QuerySet中使用它。让我们简要介绍一下查询表达式。

什么是查询表达式

查询表达式表示可以作为更新、创建、过滤、排序、注释或聚合的一部分的值或计算。如果表达式返回的是布尔值,它可以直接用于过滤。Django提供了许多内置的表达式,帮助我们编写查询。查询表达式可以嵌套或组合使用。

类F()表达式

F()对象指定了模型字段的值,或者它直接引用数据库中的模型字段值。让我们举一个简单的示例,有一个名为 Student 的班级,其中有一个字段叫做fees,我们想要增加学生的费用20%。

可以按如下方式实现。

student = Student.objects.all()
for stu in student:
    stu.fees *= 1.2

我们可以使用F()表达式在单个查询中完成这个操作。

from django.db.models import F

Student.objects.update(fees=F('fees') * 1.2)

我们还可以使用以下方法。

student = Student.objects.get(pk=1)
student.price = F('fees') * 1.2
student.save()

不过要小心处理这种任务。F()对象在保存模型后会持久存在。

student.fees                   # fees = Decimal('10.00')
student.fees = F('fees') + 1
student.save()                  # fees = Decimal('11.00')
student.name = 'What the F()'
student.save()                  # fees = Decimal('12.00')

在字段更新后,该特定字段将包含一个实例: django.db.models.expression.CombinedExpression ,而不是实际结果。我们可以立即访问结果,如下所示。

student.fees= F('fees') + 1
product.save()
print(student.fees)            # 
product.refresh_from_db()
print(student.fees)  

我们还可以使用数据的注释。

from django.db.models import ExpressionWrapper, DecimalField
Product.objects.all().annotate(
    value_in_stock=ExpressionWrapper(
        F('fees') * F('rollno'), output_field=DecimalField()
    )
)

由于 fees 是一个 DecimalField ,而 rollno 是一个 IntegerField ,我们需要将表达式包装在一个 ExpressionWrapper 对象中。

它也可以用来过滤数据。

Student.objects.filter(fees__gte=F(2000))

F()表达式可以提供以下几个优势。

  • 它可以帮助我们获得数据库,并限制Python访问数据库。
  • 它可以帮助减少特定操作的查询次数。

使用F()避免竞态条件

F() 表达式还提供了其他功能,如更新字段值来避免竞态条件。

让我们以更好的方式理解 – 如果两个Python线程执行该代码,则一个线程可以在另一个线程从数据库中检索该代码之后检索、递增和保存该代码。线程保存的值将基于原始值。第一个线程的过程将被使用。

每次涉及更新字段时,该过程将变得更加强大。当执行 save()update() 时, F() 表达式将根据数据库中字段的值来更新字段。

使用F()来排序空值

我们可以使用 F()nulls_firstnulls_last 关键字参数来控制字段空值的排序顺序。

让我们看下面的示例,对在新学期后未交费的学生进行排序。

from django.db.models import F
Student.objects.order_by(F('fees_paid').desc(nulls_last=True))

Func()表达式

Func()表达式涉及数据库函数,例如COALESCE和LOWER,或者聚合函数如SUM。我们可以直接使用它们。

示例 –

from django.db.models import F, Func
queryset.annotate(field_lower=Func(F('field'), function='LOWER'))

聚合表达式

聚合表达式是 Func() 表达式的重要组成部分。它告知查询需要 GROUP BY 子句。所有的聚合函数都继承自 Aggregate()

示例 –

from django.db.models import Count
Student.objects.annotate(
    managers_required=(Count('num_employees') /8 ) + Count('num_managers'))

Value() 表达式

Value() 对象代表表达式的最小组成部分。我们可以使用 Value() 来表示表达式内的整数、布尔或字符串值。

Value() 表达式很少直接使用。当我们编写表达式 F(‘field’) + 1 时,Django 会隐式地将1包装在 Value() 中,允许在更复杂的表达式中使用简单值。

值参数自动包含在表达式中,这些值可以是1、True或None。Django 将这些Python值转换为相应的数据库类型。而 output_field 参数必须是模型字段实例,例如 IntegerField()BooleanField()

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程