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. exVim安装

    安装 安装必备 Vim 7.3 or higher. Vundle or Pathogen 下载/更新exVim 注意事项 安装exVim将不会覆盖你已经存在的Vim环境,这个仓库所包含的文件,变化, ...

  2. HTML 标签的 enctype 属性

    定义和用法 enctype 属性规定在发送到服务器之前应该如何对表单数据进行编码. 默认地,表单数据会编码为 "application/x-www-form-urlencoded" ...

  3. ylbtech-LanguageSamples-Porperties(属性)

    ylbtech-Microsoft-CSharpSamples:ylbtech-LanguageSamples-Porperties(属性) 1.A,示例(Sample) 返回顶部 “属性”示例 本示 ...

  4. Java内存缓存

    1.缓存为什么要存在 应用服务器资源是有限的,数据库每秒中接受请求的次数也是有限的.如果利用有限的资源来提供尽可能大的吞吐量呢,一个办法:减少计 算量,缩短请求流程(减少网络io或者硬盘io),这时候 ...

  5. 关于File.separator 文件路径:window与linux下路径问题(“No such file or diretory ”异常解决方案)

    最近有个在页面上传Excel文件至服务器指定目录并进行数据校验.最后入库及进行进一步处理的应用情境,我写好代码在模拟环境下测试,完全没问题:但客户试用的时候,却老是报告“No such file or ...

  6. DevExpress中的lookupedit的使用方法详解

    摘自: http://***/zh-CN/Info/catalog/17631.html 概述:本文详细介绍了DevExpress中的lookupedit的使用方法. 绑定数据源:   1 2 3 l ...

  7. 使用MapReduce实现二度人脉搜索算法

    一,背景介绍 在新浪微博.人人网等社交网站上,为了使用户在网络上认识更多的朋友,社交网站往往提供类似“你可能感兴趣的人”.“间接关注推荐”等好友推荐的功能,其中就包含了二度人脉算法. 二,算法实现 原 ...

  8. 【Web】Django OAuth invalid_grant error

    This can happen if the code is expired. They expire pretty quickly by default. You can look up your ...

  9. Linux下解压tar.xz文件

    xz -d glib-2.14.tar.xz tar -xvf glib-2.14.tar 前面一个是将xz文件解压成tar文件,后面一个是将tar文件解压. xz使用格式:压缩: xz -z fil ...

  10. 试用cocos2dx 3.1.1

    最终有时间,開始全力投入cocos2dx开发了.之前也积累了不少.只是都是基于2.2.2的,3.1.1的版本号也出来一段时间,应该算是成熟了,今天就试试.一个最大的变化就是不须要cygwin了,直接使 ...