class F
一个 F()对象代表了一个model的字段值或注释列。使用它就可以直接参考model的field和执行数据库操作而不用再把它们查询出来放到python内存中。作为代替,Django使用 F()对象生成一个SQL表达式,来描述数据库层级所需要的操作,这些通过一个例子可以很容易的理解。往常,在数据库中获取一个数据会这样做:
(终端实验)
>>>q = OB.objects.filter(name='Tintin') >>>q[0].number += 1 (值不变)
或者:
q = OB.objects.get(name='Tintin') q.number += 1(值增加,但是并未保存进数据库,加上q.save()即可)
这里,我们把 q 的 number 属性值从数据库取出放到内存中并用我们熟悉的python运算符操作它,最后再把它保存到数据库。然而,还可以这样做:
from django.db.models import F q = OB.objects.get(name='Tintin') q.number = F('number') + 1
虽然 q[0].number = F('number') + 1 看起来像一个正常的Python分配值赋给一个实例属性,事实上这是一个描述数据库操作的SQL概念。
>>>q.number <CombinedExpression(联合表达): F(number) + Value(1)> 下面有具体例子
当Django遇到 F()实例,它覆盖了标准的Python运算符创建一个封装的SQL表达式。在这个例子中,q[0].number就代表了一个指示数据库对该字段进行增量的命令。
无论q[0].number的值是或曾是什么,Python完全不知道,这完全是由数据库去处理的。所有的Python,通过Django的F() 类,只是去创建SQL语法参考字段和描述操作。
为了获得用这种方法保存的新值,此对象应重新加载:
q = OB.objects.get(name='Tintin')
和上面单独实例的操作一样, F()配合 update()可以应用于对象实例的 QuerySets这减少了我们上面使用的两个查询 get() 和 save() 只需要使用如下方式:
>>> q = UserItem.objects.filter(name='雪碧') >>> q.update(number=F('number')+1) 1 >>> q[0].number Decimal('6')
我们可以使用update()方法批量地增加多个对象的字段值。这比先从数据库查询后,通过循环一个个增加,并一个个保存要快的很多。
UserItem.objects.all().update(number=F('number')+1)
F()表达式的效率上的优点主要体现在
1.直接通过数据库操作而不是Python
2.减少数据库查询次数
使用 F() 的另一个好处是通过数据库而不是Python来更新字段值以避免竞态条件。
如果两个Python线程执行上面第一个例子中的代码,一个线程可能在另一个线程刚从数据库中获取完字段值后获取、增加、保存该字段值。第二个线程保存的值将会基于原始字段值;第一个线程的工作将会丢失。如果让数据库对更新字段负责,这个过程将变得更稳健:它将只会在 save() 或 update()执行时根据数据库中该字段值来更新字段,而不是基于实例之前获取的字段值。同时F()在查询集和过滤器中也十分有用,它使得使用条件通过字段值而不是Python值过滤一组对象变得可能,例如:
q = OB.objects.filter(number=F('pro_number'))
直接获取了实际数量大于优惠数量的商品信息,不需要获取两个数量之后比较再存入新数组,同时搭配查询集的选择器能进行更多方便的操作。
F()可用于通过将不同字段与算术相结合来在模型上创建动态字段:
q = OB.objects.annotate(new_number=F('number') - F('pro_number')){annotate方法添加注释}
如果你组合的字段是不同类型,你需要告诉Django将返回什么类型的字段。由于F()不直接支持output_field,您需要使用Expression Wrapper
{Expression Wrapper简单地包围另一个表达式,并提供对其他表达式可能不可用的属性(例如output_field)的访问。当对 F() 的 annotations 中描述的不同类型的F()表达式使用算术时,必须使用 Expression Wrapper, class ExpressionWrapper(expression, output_field) }
from django.db.models import DateTimeField, ExpressionWrapper, F OB.objects.annotate( expires=ExpressionWrapper( F('active_a') + F('active_b'), output_field=DateTimeField()))
相关推荐
**一、F表达式** F表达式是Django提供的一个强大的工具,用于在查询中引用模型的字段。它允许你在比较操作中使用模型的字段,而无需先从数据库中获取它们。例如: ```python from django.db.models import F # ...
F表达式可以用来比较模型字段的值,而Q对象则可以构建复杂的查询条件。 6. 使用数据库索引。索引能够显著提高查询速度,特别是对于大数据集而言,建立适当索引是提高查询效率的重要手段。 7. 对于大数据集的查询,...
Q对象是Django ORM提供的一种高级查询工具,它可以让你构建复杂的查询表达式,支持AND、OR和NOT操作。例如: 1. AND关系:`Book.objects.filter(id__gt=2, bread__gt=20)` 或者 `Book.objects.filter(Q(bread__gt=...
- 使用`Q对象`可以构建复杂的查询条件,例如`Q(age__gt=30) & Q(gender='F')`表示年龄大于30且性别为女的用户。 - `exclude()`也可以接受Q对象,如`exclude(Q(age__lt=18) | Q(is_active=False))`排除未成年或未...
在Django ORM中,F对象可以创建一个字段间的表达式,允许对同一模型实例中的两个字段进行比较。而Q对象则用于构建复杂的查询条件,可以实现条件的AND、OR和NOT逻辑,从而使得构建动态查询变得更加灵活。 **values和...
在Django中,要聚合这两个模型类的数据,你可以使用查询集(QuerySet)的方法,特别是`filter()`方法配合`F()`表达式。`F()`对象允许你在查询中引用模型的字段,而无需提供实际的值。例如,如果模型A的`bookid`字段...
- **查询操作**:学习如何进行基本的查询,如查询所有、单个对象,设置过滤条件,使用查询表达式,理解QuerySet API,进行关联查询,排序和限制结果集。 - **模型的修改与删除**:学习如何更新和删除模型数据,以及...
2. **利用`F()`表达式**:在同一个模型内,使用`F()`表达式进行字段间的运算,避免Python处理,提高效率。 3. **使用`annotate()`**:对数据库进行聚合操作,如求和、平均值等,避免在Python层面处理大数据。 4. *...
Django的Aggregation功能还包括其他聚合函数,如`Sum`(求和)、`Count`(计数)、`StdDev`(标准差)、`Variance`(方差)等,以及更高级的聚合操作,如`GroupBy`和`F`表达式,它们可以用来创建更复杂的查询,如...
07 三元运算,列表解析,生成器表达式 第19章 01 生成器函数 02 生成器函数的好处 03 母鸡下蛋的传说 04 生成器特性阐释 05 生产者消费者模型 06 第三次作业讲解 第20章 01 上节课回顾 02 装饰器基本理论 03 高...