Django - ORM操作

  • Django - ORM操作
    • 一. 必知必会13条
      • 单表查询之神奇的双下划线
    • 二. ForeignKey操作
      • 正向查找
      • 反向操作
    • 三. ManyToManyField
    • 四. 聚合查询和分组查询
      • 聚合
      • 分组
    • 五. F查询和Q查询
      • F查询
      • Q查询
    • 六. 锁和事务
      • 事务
    • 七. Django ORM执行原生SQL
      • 执行原生查询
      • 直接执行自定义SQL

Django - ORM操作

一. 必知必会13条

<1> all():                 查询所有结果<2> filter(**kwargs):      它包含了与所给筛选条件相匹配的对象<3> get(**kwargs):         返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。<4> exclude(**kwargs):     它包含了与所给筛选条件不匹配的对象<5> values(*field):        返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列<6> values_list(*field):   它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列<7> order_by(*field):      对查询结果排序<8> reverse():             对查询结果反向排序,请注意reverse()通常只能在具有已定义顺序的QuerySet上调用(在model类的Meta中指定ordering或调用order_by()方法)。<9> distinct():            从返回结果中剔除重复纪录(如果你查询跨越多个表,可能在计算QuerySet时得到重复的结果。此时可以使用distinct(),注意只有在PostgreSQL中支持按字段去重。)<10> count():              返回数据库中匹配查询(QuerySet)的对象数量。<11> first():              返回第一条记录<12> last():               返回最后一条记录<13> exists():             如果QuerySet包含数据,就返回True,否则返回False

 

返回QuerySet对象的方法有

  • all()

  • filter()

  • exclude()

  • order_by()

  • reverse()

  • distinct()

特殊的QuerySet

  • values() 返回一个可迭代的字典序列

  • values_list() 返回一个可迭代的元祖序列

返回具体对象的

  • get()

  • first()

  • last()

返回布尔值的方法有:

  • exists()

返回数字的方法有

  • count()

单表查询之神奇的双下划线

models.Book.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值
 
models.Book.objects.filter(id__in=[11, 22, 33])   # 获取id等于11、22、33的数据
models.Book.objects.exclude(id__in=[11, 22, 33])  # not in
 
models.Book.objects.filter(name__contains="v")  # 获取name字段包含"v"的
models.Book.objects.filter(name__icontains="v") # icontains大小写不敏感
 
models.Book.objects.filter(id__range=[1, 3])      # id范围是1到3的,等价于SQL的bettwen and
 
类似的还有:startswith,istartswith, endswith, iendswith date字段还可以:
models.Class.objects.filter(first_day__year=2017)

 

二. ForeignKey操作

正向查找

对象查找(跨表)
语法:

对象.关联字段.字段

示例:

book_obj = models.Book.objects.first()  # 第一本书对象
print(book_obj.publisher)  # 得到这本书关联的出版社对象
print(book_obj.publisher.name)  # 得到出版社对象的名称

 

字段查找(跨表
语法:

关联字段__字段

示例:

print(models.Book.objects.values_list("publisher__name"))

 

反向操作

对象查找
语法:

obj.表名_set

示例:

publisher_obj = models.Publisher.objects.first()  # 找到第一个出版社对象
books = publisher_obj.book_set.all()  # 找到第一个出版社出版的所有书
titles = books.values_list("title")  # 找到第一个出版社出版的所有书的书名

 

字段查找
语法:

表名__字段

示例:

titles = models.Publisher.objects.values_list("book__title")

 

三. ManyToManyField

create()

创建一个新的对象,保存对象,并将它添加到关联对象集之中,返回新创建的对象。

>>> import datetime
>>> models.Author.objects.first().book_set.create(title="番茄物语", publish_date=datetime.date.today())

 

add()

把指定的model对象添加到关联对象集中。

添加对象

>>> author_objs = models.Author.objects.filter(id__lt=3)
>>> models.Book.objects.first().authors.add(*author_objs)

 

添加id

>>> models.Book.objects.first().authors.add(*[1, 2])

 

set()

更新model对象的关联对象。

>>> book_obj = models.Book.objects.first()
>>> book_obj.authors.set([2, 3])

 

remove()

从关联对象集中移除执行的model对象

>>> book_obj = models.Book.objects.first()
>>> book_obj.authors.remove(3)

 

clear()

从关联对象集中移除一切对象。

>>> book_obj = models.Book.objects.first()
>>> book_obj.authors.clear()

 

注意:

对于ForeignKey对象,clear()和remove()方法仅在null=True时存在。

举个例子:

ForeignKey字段没设置null=True时,

class Book(models.Model):
title = models.CharField(max_length=32)
publisher = models.ForeignKey(to=Publisher)

 

没有clear()和remove()方法:

>>> models.Publisher.objects.first().book_set.clear()
Traceback (most recent call last):File "<input>", line 1, in <module>
AttributeError: 'RelatedManager' object has no attribute 'clear'

 

当ForeignKey字段设置null=True时,

class Book(models.Model):name = models.CharField(max_length=32)publisher = models.ForeignKey(to=Class, null=True)

 

此时就有clear()和remove()方法:

>>> models.Publisher.objects.first().book_set.clear()

 

注意:

对于所有类型的关联字段,add()、create()、remove()和clear(),set()都会马上更新数据库。换句话说,在关联的任何一端,都不需要再调用save()方法。

四. 聚合查询和分组查询

聚合

aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。

键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。

示例:

>>> from django.db.models import Avg, Sum, Max, Min, Count
>>> models.Book.objects.all().aggregate(Avg("price"))
{'price__avg': 13.233333}

 

如果你想要为聚合值指定一个名称,可以向聚合子句提供它。

>> models.Book.objects.aggregate(average_price=Avg('price'))
{'average_price': 13.233333}

 

如果你希望生成不止一个聚合,你可以向aggregate()子句中添加另一个参数。所以,如果你也想知道所有图书价格的最大值和最小值,可以这样查询:

>> models.Book.objects.all().aggregate(Avg("price"), Max("price"), Min("price"))
{'price__avg': 13.233333, 'price__max': Decimal('19.90'), 'price__min': Decimal('9.90')}

 

分组

我们在这里先复习一下SQL语句的分组。

假设现在有一张公司职员表:

我们使用原生SQL语句,按照部分分组求平均工资:

select dept,AVG(salary) from employee group by dept;

 

ORM查询:

from django.db.models import Avg
Employee.objects.values("dept").annotate(avg=Avg("salary").values(dept, "avg")

 

连表查询的分组:

SQL查询:

select dept.name,AVG(salary) from employee inner join dept on (employee.dept_id=dept.id) group by dept_id;

 

ORM查询:

from django.db.models import Avg
models.Dept.objects.annotate(avg=Avg("employee__salary")).values("name", "avg")

 

五. F查询和Q查询

F查询

在上面所有的例子中,我们构造的过滤器都只是将字段值与某个常量做比较。如果我们要对两个字段的值做比较,那该怎么做呢?

Django 提供 F() 来做这样的比较。F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。

示例1:

查询评论数大于收藏数的书籍from django.db.models import F
models.Book.objects.filter(commnet_num__gt=F('keep_num'))Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。models.Book.objects.filter(commnet_num__lt=F('keep_num')*2)修改操作也可以使用F函数,比如将每一本书的价格提高30元models.Book.objects.all().update(price=F("price")+30)

 

引申:

如果要修改char字段咋办?

如:把所有书名后面加上(第一版)

>>> from django.db.models.functions import Concat
>>> from django.db.models import Value
>>> models.Book.objects.all().update(title=Concat(F("title"), Value("("), Value("第一版"), Value(")")))

 

Q查询

filter() 等方法中的关键字参数查询都是一起进行“AND” 的。 如果你需要执行更复杂的查询(例如OR语句),你可以使用Q对象。

示例1:

查询作者名是小仙女或小魔女的

models.Book.objects.filter(Q(authors__name="小仙女")|Q(authors__name="小魔女"))

 

你可以组合& 和| 操作符以及使用括号进行分组来编写任意复杂的Q 对象。同时,Q 对象可以使用~ 操作符取反,这允许组合正常的查询和取反(NOT) 查询。

示例:查询作者名字是小仙女并且不是2018年出版的书的书名。

>>> models.Book.objects.filter(Q(author__name="小仙女") & ~Q(publish_date__year=2018)).values_list("title")
<QuerySet [('番茄物语',)]>

 

查询函数可以混合使用Q 对象和关键字参数。所有提供给查询函数的参数(关键字参数或Q 对象)都将"AND”在一起。但是,如果出现Q 对象,它必须位于所有关键字参数的前面。

例如:查询出版年份是2017或2018,书名中带物语的所有书。

>>> models.Book.objects.filter(Q(publish_date__year=2018) | Q(publish_date__year=2017), title__icontains="物语")
<QuerySet [<Book: 番茄物语>, <Book: 香蕉物语>, <Book: 橘子物语>]>

 

六. 锁和事务

select_for_update(nowait=False, skip_locked=False)

返回一个锁住行直到事务结束的查询集,如果数据库支持,它将生成一个 SELECT ... FOR UPDATE 语句。

举个例子:

entries = Entry.objects.select_for_update().filter(author=request.user)

 

所有匹配的行将被锁定,直到事务结束。这意味着可以通过锁防止数据被其它事务修改。

一般情况下如果其他事务锁定了相关行,那么本查询将被阻塞,直到锁被释放。 如果这不想要使查询阻塞的话,使用select_for_update(nowait=True)。 如果其它事务持有冲突的锁, 那么查询将引发 DatabaseError 异常。你也可以使用select_for_update(skip_locked=True)忽略锁定的行。 nowait和skip_locked是互斥的,同时设置会导致ValueError。

目前,postgresql,oracle和mysql数据库后端支持select_for_update()。 但是,MySQL不支持nowait和skip_locked参数。

使用不支持这些选项的数据库后端(如MySQL)将nowait=True或skip_locked=True转换为select_for_update()将导致抛出DatabaseError异常,这可以防止代码意外终止。

事务

import osif __name__ == '__main__':os.environ.setdefault("DJANGO_SETTINGS_MODULE", "BMS.settings")import djangodjango.setup()import datetimefrom app01 import modelstry:from django.db import transactionwith transaction.atomic():new_publisher = models.Publisher.objects.create(name="火星出版社")models.Book.objects.create(title="橘子物语", publish_date=datetime.date.today(), publisher_id=10)  # 指定一个不存在的出版社idexcept Exception as e:print(str(e))

 

七. Django ORM执行原生SQL

Django 提供两种方法使用原始SQL进行查询:一种是使用raw()方法,进行原始SQL查询并返回模型实例;另一种是完全避开模型层,直接执行自定义的SQL语句。

执行原生查询

raw()管理器方法用于原始的SQL查询,并返回模型的实例:注意:raw()语法查询必须包含主键。这个方法执行原始的SQL查询,并返回一个django.db.models.query.RawQuerySet 实例。 这个RawQuerySet 实例可以像一般的QuerySet那样,通过迭代来提供对象实例。举个例子:class Person(models.Model):first_name = models.CharField(...)last_name = models.CharField(...)birth_date = models.DateField(...)
可以像下面这样执行原生SQL语句>>> for p in Person.objects.raw('SELECT * FROM myapp_person'):
...     print(p)
raw()查询可以查询其他表的数据。举个例子:ret = models.Student.objects.raw('select id, tname as hehe from app02_teacher')for i in ret:print(i.id, i.hehe)
raw()方法自动将查询字段映射到模型字段。还可以通过translations参数指定一个把查询的字段名和ORM对象实例的字段名互相对应的字典d = {'tname': 'haha'}ret = models.Student.objects.raw('select * from app02_teacher', translations=d)for i in ret:print(i.id, i.sname, i.haha)
原生SQL还可以使用参数,注意不要自己使用字符串格式化拼接SQL语句,防止SQL注入!d = {'tname': 'haha'}ret = models.Student.objects.raw('select * from app02_teacher where id > %s', translations=d, params=[1,])for i in ret:print(i.id, i.sname, i.haha)

 

直接执行自定义SQL

有时候raw()方法并不十分好用,很多情况下我们不需要将查询结果映射成模型,或者我们需要执行DELETE、 INSERT以及UPDATE操作。在这些情况下,我们可以直接访问数据库,完全避开模型层。

我们可以直接从django提供的接口中获取数据库连接,然后像使用pymysql模块一样操作数据库。

from django.db import connection, connections
cursor = connection.cursor()  # cursor = connections['default'].cursor()
cursor.execute("""SELECT * from auth_user where id = %s""", [1])
ret = cursor.fetchone()

 

转载于:https://www.cnblogs.com/Ryan-Yuan/p/11553394.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/482359.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从王者荣耀AI看人工智能与游戏结合的未来意义

来源&#xff1a;央广网国际在线消息&#xff1a;3月18日&#xff0c;成都大运会倒计时100天之际&#xff0c;由大运会执委会主办&#xff0c;腾讯承办的“世界大学生数智竞技邀请赛”正式启动。这次邀请赛将融合科技、文化、竞技的赛场精神&#xff0c;以《王者荣耀》和腾讯AI…

String源码分析

最近开始阅读java底层的源码&#xff0c;是因为发现越到后面越发现读源码的重要性&#xff0c;真的很重要&#xff0c;不阅读源码&#xff0c;你会发现“路”越走越窄。 今天看到了String的这个构造方法&#xff0c; /*** Initializes a newly created {code String} object so…

575万奖金!2022年数学界「诺贝尔奖」发布,拓扑学大师获奖

来源&#xff1a;AI科技评论作者&#xff1a;西西编辑&#xff1a;陈彩娴3月22日晚&#xff0c;被誉为数学界「诺贝尔奖」的阿贝尔奖揭晓。2022年&#xff0c;挪威科学院决定将阿贝尔奖授予来自美国纽约市立大学研究生院的阿尔伯特爱因斯坦讲座教授、纽约州立大学石溪分校的教授…

为什么深度学习是非参数的?

来源&#xff1a;AI科技评论作者&#xff1a;Thomas Viehmann编译&#xff1a;钱磊编辑&#xff1a;陈彩娴今天我想要与大家分享的是深度神经网络的工作方式&#xff0c;以及深度神经与“传统”机器学习模型的不同之处。我的计划具体如下&#xff1a;首先简单地思考一下如何将问…

“一束光”让机器人也能拥有触觉?之江实验室这项技术惊艳世界

来源&#xff1a;浙江日报传递触觉的“特殊道路”我们对这个世界最初的感知通常是从触觉开始的——第一声啼哭之前&#xff0c;婴儿经历过诱发哭声的拍打&#xff1b;成长中提笔、拍球&#xff1b;生活中握手&#xff0c;敲击键盘&#xff0c;使用手机……触觉充斥着我们日常生…

图书管理系统~简单流程

1. 连接数据库 2. 路由url (网站目录) 2.1若要从URL 中捕获一个值&#xff0c;只需要在它周围放置一对圆括号。&#xff08;分组&#xff09;2.2使用简单的、没有命名的正则表达式组&#xff08;通过圆括号&#xff09;来捕获URL中的值并以位置 参数传递给视图。在更高级的用法…

7年前轰动全球的Science论文,被发现可能搞错了

来源&#xff1a;iNature蛇是一个非常多样化和成功的群体&#xff0c;但它们的进化起源是模糊的。两条腿蛇的发现揭示了从蜥蜴到蛇的过渡&#xff0c;但没有描述过四条腿蛇&#xff0c;早期蛇的生态知之甚少。2015年7月24日&#xff0c;英国朴茨茅斯大学David M. Martill等人在…

Django - AJAX

一. JSON 什么是json? json指的是JavaScript对象表示法(JavaScript Object Notation)json是轻量级的文本数据交换格式独立于语言, 支持不同的编程语言具有自我描述性, 跟易理解合格的json对象: ["one", "two", "three"] { "one": 1, …

培育强人工智能的「ImageNet」:上海交大卢策吾组提出铰接物体知识库 AKB-48

来源&#xff1a;前沿科技编译&#xff1a;OGAI编辑&#xff1a;陈彩娴ImageNet 的出现极大推动了计算机视觉领域的发展。在通往强人工智能的路上&#xff0c;我们还需要考虑物体的外观、结构、物理性质、语义等因素。为此&#xff0c;上海交大卢策吾组近日重磅推出了大型真实世…

模块化认知:演化如何自下而上涌现出智能?

来源&#xff1a; 集智俱乐部作者&#xff1a;Michael Levin, Rafael Yuste译者&#xff1a;郭瑞东审校&#xff1a;刘志航、梁金 编辑&#xff1a;邓一雪 导语无论是聪明的人、哺乳动物、鸟类&#xff0c;还是细胞和组织、神经元网络、病毒以及蛋白质分子&#xff0c;在所有尺…

Stuart Russell:智能本质和人工智能安全的巨大挑战

斯图尔特罗素&#xff08;Stuart Russell&#xff09;&#xff0c;加州大学伯克利分校计算机科学专业教授&#xff0c;著有人工智能领域“标准教科书”——《人工智能&#xff1a;一种现代化方法》&#xff08;与谷歌研究主管Peter Norvig合著&#xff09;来源&#xff1a;智能…

费马大定理:三百年数学圣杯的角逐

来源&#xff1a;和乐数学费马大定理&#xff0c;又被称为“费马最后的定理”。人类前赴后继挑战了三个世纪&#xff0c;多次震惊全世界&#xff0c;耗尽人类众多最杰出大脑的精力&#xff0c;也让千千万万业余者痴迷。费马大定理的故事与数学的历史有着千丝万缕的联系&#xf…

Django - Form和ModelForm

一. form介绍 1.生成页面可用的HTML标签 2. 提供input可以提交数据 3. 对用户提交的数据进行校验 4. 保留上次输入内容 5. 提供错误信息 二. 普通方式书写注册功能 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8">&…

人工智能,“抛弃”真实数据集?

来源&#xff1a;学术头条当前&#xff0c;人工智能技术已经应用在我们日常生活中的方方面面&#xff0c;比如人脸识别、语音识别、虚拟数字人等。但普遍存在的一个问题是&#xff0c;科研人员要想通过训练一个机器学习模型来执行某一特定任务&#xff08;比如图像分类&#xf…

Django - Cookie和Session

Django - Cookie和Session cookie Django中操作CookieCookie版登陆校验Session Django中Session相关方法Session流程解析Session版登陆验证Django中的Session配置Django - Cookie和Session cookie Cookie的由来 大家都知道HTTP协议是无状态的。 无状态的意思是每次请求都是独立…

一文说清AI智能平台

来源&#xff1a;海豚数据科学实验室有一天&#xff0c;小李的领导说&#xff1a;“我们要做AI平台&#xff01;”。虽然平台产品也不是新概念了&#xff0c;随着AI技术的成熟&#xff0c;AI平台产品也越来越多&#xff0c;但光凭做平台一句话&#xff0c;小李还是犯了难——大…

2D图像转3D仅需5秒,特斯拉的自动驾驶技术有救了?

来源&#xff1a;科技智谷编译&#xff1a;徐浩75年前&#xff0c;宝丽来相机拍摄出第一张即时照片&#xff0c;是人类第一次以逼真的二维图像快速捕捉三维世界&#xff0c;具有划时代的意义。今天&#xff0c;人工智能的研究人员正在进行相反的工作&#xff0c;力求在几秒钟的…

Django - 中间件

Django - 中间件 一. 什么是中间件 官方: 中间件是一个用来处理Django的请求和相应的框架级别的钩子, 他是一个轻量, 低级别的插件系统, 用于在全局范围内改变Django的输入和输出, 每个中间件都负责做一些特定的功能. 大白话: 中间件是帮助我们在视图函数执行之前和执行之后都可…

回答薛定谔问题: 生命是什么?自由能公式

来源&#xff1a;CreateAMind回答薛定谔的问题:自由能公式麦克斯韦詹姆斯德索莫拉姆斯泰德a,b,∗保罗本杰明巴德科克c,d,e,卡尔约翰弗里斯顿f,1加拿大魁北克蒙特利尔麦吉尔大学哲学系加拿大魁北克蒙特利尔麦吉尔大学精神病学系社会和跨文化精神病学分部c墨尔本大学心理科学学院…

AlphaCode能替代人类程序员吗?网友:被替代也挺好,这样就可以少写代码多开会了...

来源&#xff1a;AI前线作者&#xff1a;Ben Dickson译者&#xff1a;王强策划&#xff1a;冬梅本文属于我们的人工智能研究论文评论系列&#xff0c;这个系列旨在探讨人工智能领域的最新研究成果。DeepMind 是最新的人工智能研究实验室。它推出了一个可以生成软件源代码的深度…