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. 【LaTeX】E喵的LaTeX新手入门教程(3)数学公式

    昨天熄灯了真是坑爹.前情回顾[LaTeX]E喵的LaTeX新手入门教程(1)准备篇 [LaTeX]E喵的LaTeX新手入门教程(2)基础排版上一期测试答案1.大家一开始想到的肯定是\LaTeX{}er ...

  2. [NS2]TCL语言基本语法

    (来自:<NS2仿真实验-多媒体和无线网络通信>) 1. 变量(Variable)和变量替换(Variable Substitution) tcl变量是在第一次使用set的指令来指派变量的 ...

  3. Ajax和Jsonp实践

    之前一直使用jQuery的ajax方法,导致自己对浏览器原生的XMLHttpRequest对象不是很熟悉,于是决定自己写下,以下是个人写的deom,发表一下,聊表纪念. Ajax 和 jsonp 的j ...

  4. Windows Server 2008 远程桌面连接拒绝

    (1)远程连接的时候在本地用户名添加域名 现象:在Windows2008R2配置成域控制器前,还没有安装AD,管理员Admistrator以及新创建的用户(创建的时候将该用户加入远程桌面管理组),发现 ...

  5. ylbtech-LanguageSamples-Indexers(索引器)

    ylbtech-Microsoft-CSharpSamples:ylbtech-LanguageSamples-Indexers(索引器) 1.A,示例(Sample) 返回顶部 “索引器”示例 本示 ...

  6. 使用node中的express解决vue-cli加载不到dev-server.js的问题

    在使用vue开发过程中,难免需要去本地数据地址进行请求,而原版配置在dev-server.js中,新版vue-webpack-template已经删除dev-server.js,改用webpack.d ...

  7. 在Oracle 11.2.0.1.0下dbms_stats.gather_table_stats收集直方图不准

    SQL> select * from v$version; BANNER ------------------------------------------------------------ ...

  8. php 基于cookie的sessIon机制

    session_start()是session机制的开始,它有一定概率开启垃圾回收,因为session是存放在文件中,PHP自身的垃圾回收是无效的,SESSION的回收是要删文件的,这个概率是根据ph ...

  9. 封装自用的脚本ajax.js

    function createxmlhttp() { xmlhttpobj = false; try{//创建对象,一个一个的试,哎,要是能统一标准都好.. xmlhttpobj = new XMLH ...

  10. PHP和数据访问之(插入。删除。和更新数据)

    插入: <?php $conn=@new mysqli('localhost','root','123','mytestdb'); $q_str=<<<EOM insert i ...