在Django中使用F()函数
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()函数的更多相关文章
- Django中的F和Q函数
内容简介: 介绍Django中的F和Q作用以及使用方法 一.F介绍 作用:操作数据表中的某列值,F()允许Django在未实际链接数据的情况下具有对数据库字段的值的引用,不用获取对象放在内存中再对字段 ...
- django中的F和Q
F查询 Django 提供 F() 来做这样的比较.F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值. 查询书id大于\小于价格的书籍 models.Book.ob ...
- Django中的path函数
path( )作用:解析URL地址 path( ) 标准语法: (<>为必须的参数,[]为可选参数) path(<route>, <view>, [name=Non ...
- Django中的prefetch_related()函数优化
对于多对多字段(ManyToManyField)和一对多字段, 可以使用prefetch_related()来进行优化 prefetch_related()和select_related()的设计目的 ...
- Django 中的select_related函数优化查询
参考链接: https://blog.csdn.net/secretx/article/details/43964607 在数据库有外键的时候,使用select_related()和prefech_r ...
- Django中使用locals()函数的技巧
对 current_datetime 的一次赋值操作: def current_datetime(request): now = datetime.datetime.now() return rend ...
- django中的locale()函数
就是可以将函数中的变量与其对应的值,自动包裹成字典传到静态页面 参考链接:http://www.jb51.net/article/69558.htm
- django中聚合aggregate和annotate GROUP BY的使用方法
接触django已经很长时间了,但是使用QuerySet查询集的方式一直比较低端,只会使用filter/Q函数/exclude等方式来查询,数据量比较小的时候还可以,但是如果数据量很大,而且查询比较复 ...
- django中的跨表查询梳理
1.前言 最近在写一个小项目,里面主要涉及的就是表与表之间复杂的关系.当真正开发起来的时候,才发现自己对复杂的表关系间的查询有点混乱,趁着这几天的时间,重新梳理了一下. 2.概念 在开始之前,先明确几 ...
随机推荐
- javascript正则中ASCII与unicode
正则表达式中允许直接利用ASCII和Unicode编码来查找我们相应的字符串. ASCII: 下面是检索ASCII编码在x41-x7a范围内的所有匹配的字符串.(x41,x7a为十六进制) var s ...
- iOS:键盘弹出和收起的通知使用
介绍:不论是UITextField,还是UITextView,使用它们输入文字时都是有键盘的弹出,此时可能会挡住我们创建的一分部其他视图,此时,就需要根据键盘的高度将我们被隐藏的部分View做向上或者 ...
- iOS:多线程技术GCD的使用
GCD的使用: 1.队列的类型 1.1 主队列:mian queue,主线程队列,负责更行UI的操作.是一个串行的队列. 1.2 系统默认的并行队列:global queue,按优 ...
- 2018年3月python传智播客人工智能基础就业班全套视频教程
2018年3月python传智播客人工智能基础就业班全套视频教程 有需要的可以留言留下邮箱.
- KMP字符串模式匹配详解(zz)
刚看到位兄弟也贴了份KMP算法说明,但本人觉得说的不是很详细,当初我在看这个算法的时候也看的头晕昏昏的,我贴的这份也是网上找的.且听详细分解: KMP字符串模式匹配详解 来自CSDN A_B_ ...
- Maven nexus 安装nexus私服出现的两个问题
1. 在win10中安装nexus时提示:wrapper | OpenSCManager failed - 拒绝访问. (0x5) 主要是没有权限.需要以管理员的身份运行 如果你是直接点击 start ...
- 使用MyEclipse 2014构建Maven项目的两种方法
前提: MyEclipse已配置Maven,具体步骤见http://blog.csdn.net/haishu_zheng/article/details/51492491 方法一: 1 File--& ...
- Win7双屏显示设置
双显示器:一个是T410自己的屏幕,一个是宏基的Acer1296*768显示器. 连接:将宏基显示器的Display端子连接到笔记本的Display口上,电源接上. 设置过程: 1.右键点屏幕,选“S ...
- java中Xml、json之间的相互转换
旁白: 最近关于xml与json之间的转换都搞蒙了,这里写一个demo,以后备用. 正题: project格式是: jar包是一个一个检出来的,还算干净了. 代码: 工具类: package exer ...
- Handler(2)
andriod提供了Handler 和 Looper 来满足线程间的通信.Handler先进先出原则.Looper类用来管理特定线程内对象之间的消息交换(MessageExchange). 1)Loo ...