F()允许Django在未实际链接数据的情况下具有对数据库字段的值的引用。通常情况下我们在更新数据时需要先从数据库里将原数据取出后方在内存里,然后编辑某些属性,最后提交。例如这样

# Tintin filed a news story!
reporter = Reporters.objects.get(name='Tintin')
reporter.stories_filed += 1
reporter.save()
 

上述代码中我们先将reporter.stories_filed的值从数据库中取出放到内存中然后利用python的语法操作计算出新的值之后调用save()方法保存回数据库最终生成是SQL语句有可能是类似

updatereporterset stores_filed = 20 wherename = 'smp'; --20可能是经过计算之后得到的值。
 

而我们知道其实我们的需求其实可以理解成SQL:

updatereporterset stores_filed = stores_filed+1 wherename = 'smp'
 

解决

而F()函数的左右就是直接生成SQL语句来描述类似的需求,看下面代码:

fromdjango.db.modelsimport F
 
reporter = Reporters.objects.get(name='Tintin')
reporter.stories_filed = F('stories_filed') + 1
reporter.save()
 

虽然代码 reporter.stories_filed = F('stories_filed') + 1 有点类似python风格的代码,但实际上却能生成SQL语句直接描述对数据库的操作。

当Django程序中出现F()时,Django会使用SQL语句的方式取代标准的Python操作。

上述代码中不管 reporter.stories_filed 的值是什么,Python都不曾获取过其值,python做的唯一的事情就是通过Django的F()函数创建了一条SQL语句然后执行而已。

需要注意的是在使用上述方法更新过数据之后需要重新加载数据来使数据库中的值与程序中的值对应:

reporter = Reporters.objects.get(pk=reporter.pk)

或者使用更加简单的方法:

reporter.refresh_from_db()

更新多条数据

与上面的在一个对象中操作的例子相似,F()函数同样可以使用在查询集中,配合update()方法。这样我们同样可以将更新的两步合并成一步:

reporter = Reporters.objects.filter(name='Tintin')
reporter.update(stories_filed=F('stories_filed') + 1)
 

我们同样可以使用 update() 方法增加或者更改字段的值,这样做的效率比将其取到内存中后再一个个计算值再更新数据库的效率会提高非常多。

Reporter.objects.all().update(stories_filed=F('stories_filed') + 1)
 

组合使用

F()函数可以在创建模型时根据已知的N个字段组合出另外的字段数据,看下面的例子:

company = Company.objects.annotate(
    chairs_needed=F('num_employees') - F('num_chairs'))
 

但是如果组合的两个字段拥有不同的数据类型,那么咱们需要手动告诉Django新生成的数据类似是什么,看下面的列子:

fromdjango.db.modelsimportDateTimeField, ExpressionWrapper, F
 
Ticket.objects.annotate(
    expires=ExpressionWrapper(
        F('active_at') + F('duration'), output_field=DateTimeField()))
 

上述代码描述了个过期时间的概念,数据库中保存的是激活时间和持续时间,并且通过参数 output_field 告诉 expires 的类型为 DateTimeField

在Django中使用F()函数的更多相关文章

  1. Django中的F和Q函数

    内容简介: 介绍Django中的F和Q作用以及使用方法 一.F介绍 作用:操作数据表中的某列值,F()允许Django在未实际链接数据的情况下具有对数据库字段的值的引用,不用获取对象放在内存中再对字段 ...

  2. django中的F和Q

    F查询 Django 提供 F() 来做这样的比较.F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值. 查询书id大于\小于价格的书籍 models.Book.ob ...

  3. Django中的path函数

    path( )作用:解析URL地址 path( ) 标准语法: (<>为必须的参数,[]为可选参数) path(<route>, <view>, [name=Non ...

  4. Django中的prefetch_related()函数优化

    对于多对多字段(ManyToManyField)和一对多字段, 可以使用prefetch_related()来进行优化 prefetch_related()和select_related()的设计目的 ...

  5. Django 中的select_related函数优化查询

    参考链接: https://blog.csdn.net/secretx/article/details/43964607 在数据库有外键的时候,使用select_related()和prefech_r ...

  6. Django中使用locals()函数的技巧

    对 current_datetime 的一次赋值操作: def current_datetime(request): now = datetime.datetime.now() return rend ...

  7. django中的locale()函数

    就是可以将函数中的变量与其对应的值,自动包裹成字典传到静态页面 参考链接:http://www.jb51.net/article/69558.htm

  8. django中聚合aggregate和annotate GROUP BY的使用方法

    接触django已经很长时间了,但是使用QuerySet查询集的方式一直比较低端,只会使用filter/Q函数/exclude等方式来查询,数据量比较小的时候还可以,但是如果数据量很大,而且查询比较复 ...

  9. django中的跨表查询梳理

    1.前言 最近在写一个小项目,里面主要涉及的就是表与表之间复杂的关系.当真正开发起来的时候,才发现自己对复杂的表关系间的查询有点混乱,趁着这几天的时间,重新梳理了一下. 2.概念 在开始之前,先明确几 ...

随机推荐

  1. [转]使用SSIS创建同步数据库数据任务

    本文转自:http://www.cnblogs.com/heqichang/archive/2012/09/19/2693214.html SSIS(SQL Server Integration Se ...

  2. cpu gpu数据同步

    https://developer.apple.com/documentation/metal/advanced_command_setup/cpu_and_gpu_synchronization d ...

  3. echarts图形报表缓存问题(option数据缓存)

    这几天我在工作中用到了echarts开发报表.每次查询出来的数据都是新的,但是echart展现的图形报表却还是之前的数据.网上找了搜索了很多次也没能解决,后面加了技术群才解决的. 我开始已经确定是报表 ...

  4. Maven+SpringMVC+Freemarker入门Demo

    1 参考http://blog.csdn.net/haishu_zheng/article/details/51490299,用第二种方法创建一个名为mavenspringmvcfreemarker的 ...

  5. BEA公司的weblogic是什么?有什么特点?

    转自:http://zhidao.baidu.com/link?url=J9obKwHhuh1sdLoBC3pILeaq1nz_tcpScggBNeS3D0GzAz9FI002vlS2xxJD4_z6 ...

  6. java集合Collection接口

    collection集合 Map集合 Hashtable和HashMap的区别: Hashtable的方法是同步的,而HashMap的方法不是.HashMap可以将空值作为一个表的条目的key或val ...

  7. Core Data 多表连接及查询

    一:先建议两张表 Person,Score 分别代表,学生表,分数表 在 Person的Relationships里面建立关系,指向分数score 二:coreData生成的两个表: Person @ ...

  8. vc 获取函数名称真实地址

    首先写一个很简单的main函数: int main(){ printf("main的地址(?):%08x",main); } 单步调试,可得知 main函数的真实入口地址是:00b ...

  9. Visual Studio 2015下编译zmq项目下其他项目踩进的项目引用坑

    PS.在之前的一篇文章中介绍了如何用Visual Studio 2015编译zmq,在编译同解决方案中除了libzmq之外的项目例如inproc_thr时会报错误,具如下: Severity Code ...

  10. hibernate 启动和辅助类实现资源的重复使用

    来自API: 1.2.5.  启动和辅助类 是时候来加载和储存一些Event对象了,但首先我们得编写一些基础的代码以完成设置.我们必须启动Hibernate,此过程包括创建一个全局的SessoinFa ...