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. Hive 内建操作符与函数开发——深入浅出学Hive

    第一部分:关系运算 Hive支持的关系运算符 •常见的关系运算符 •等值比较: = •不等值比较: <> •小于比较: < •小于等于比较: <= •大于比较: > •大 ...

  2. Jenkins的slave异常:Exception in thread "main" java.lang.ClassNotFoundException: hudson.remoting.Launcher

    当任务分配到slave上执行时,报如下错误: Parsing POMs Established TCP socket on 38257 maven33-agent.jar already up to ...

  3. python部署工具fabric

    两台机器:10.1.6.186.10.1.6.159.fabric部署在10.1.6.186上面 1  执行和1相同的任务,不过排除掉10.1.6.159这台机器 1 #!/usr/bin/pytho ...

  4. phpMyAdmin配置

    一: (1):下载phpmyadmin,在官方最好               (2):个人建议最好将其安装在apache的htdocs文件中(apache的默认虚拟目录,或web访问目录)      ...

  5. ISP图像调试工程师——自动白平衡(熟悉3A算法)

    http://blog.csdn.net/wzwxiaozheng/article/details/40586293 https://wenku.baidu.com/view/24632048767f ...

  6. JS前端下载文本文件小技巧:1、download属性;2、借助Blob转换成二进制下载

    一.HTML download 与文件下载 如果希望在前端侧直接触发某些资源的下载,最方便快捷的方法就是使用HTML5原生的download属性,例如: <a href="large. ...

  7. Flex的 Event中属性currentTarget与target的差别

    Flex的 Event中属性currentTarget与target的差别 1.差别 (1)currentTarget是事件的处理对象(event processor) (2)target是事件的调用 ...

  8. 【笔记】js原生方法 在元素外部或内部实现添加元素功能(类似jq 的 insert 和 append)

    介绍的这个方法是:insetAdjacentHTML() 方法 此方法接收两个参数: 第一个参数必为下列值: beforebegin:在调用的元素外部的前面添加一个目标元素 afterend:在调用元 ...

  9. Android avd XDM authorization key matches an existing client

    在启动 android avd 调试程序的时候,突然出现这个错误; XDM authorization key matches an existing client avd 怎么也启动不起来.网上搜也 ...

  10. Python中的关键字的用法

    Python有哪些关键字 -Python常用的关键字 and, del, from, not, while, as, elif, global, or, with, assert, else, if, ...