django orm操作,
创建一个模型实例:让我们假设以下概念、字段和关系。
作者:作者有名字和年龄。
作者模型:在详细列表中放入作者的详细信息,包括出生日期、手机号码、家庭住址等信息。作者细节模型和作者模型之间是一对一的关系。
发布者模型:发布者有姓名、城市和电子邮件。
图书模型:图书有书名和出版日期,一本书可能有多个作者,一个作者也可以写多本书,所以作者和图书的关系是多对多关系(多对多);一本书应该只由一家出版社出版,所以出版社和书是一对多的关系。
该模型建立如下:
从django.db导入模型
#在此创建您的模型。
类作者(模型。型号):
nid=模型。AutoField(primary_key=True)
名称=型号。CharField( max_length=32)
年龄=模特。IntegerField()
#与AuthorDetail建立一对一的关系
authorDetail=models。OneToOneField(to=AuthorDetail ,on_delete=models。级联)
类AuthorDetail(模型。型号):
nid=模型。AutoField(primary_key=True)
生日=模特。日期字段()
电话=型号。BigIntegerField()
addr=型号。CharField( max_length=64)
类发布(模型。型号):
nid=模型。AutoField(primary_key=True)
名称=型号。CharField( max_length=32)
城市=模特。CharField( max_length=32)
邮件=模特。电子邮件字段()
课堂用书(模型。型号):
nid=模型。AutoField(primary_key=True)
标题=模型。CharField( max_length=32)
发布日期=模型。日期字段()
价格=车型。DecimalField(max_digits=5,decimal_places=2)
#与Publish建立一对多关系,外键字段建立在many的一侧。
发布=模型。ForeignKey(to=Publish ,to_field=nid ,on_delete=models。级联)
#与作者表建立多对多关系。ManyToManyField可以在这两个模型中的任何一个中构建,并自动创建第三个表。
作者=模型。ManyToManyField(to=Author ,)
生成的表格如下:
注意事项:
表名myapp_modelName是根据模型中的元数据自动生成的,也可以用另一个名称覆盖。id字段会自动添加。对于外键字段,Django将在字段名中添加 _id 来创建数据库中的列名。本例中的CREATE TABLE SQL语句使用PostgreSQL语法格式,需要注意的是Django会根据设置中指定的数据库类型使用相应的SQL语句。在定义了模型之后,您需要告诉Django使用这些模型。您所要做的就是在配置文件中修改INSTALL_APPSZ中的设置,并添加models.py所在的应用程序的名称。ForeignKey字段foreignkey有一个NULL=True设置(它允许外键接受空值),您可以为它分配一个空值None。
在添加表记录之前,只需输入一些数据:
发布表格:
作者表:
Authordetail表:
一对多#模式1:
publish _ obj=publish . objects . get(NID=1)
book _ obj=book . objects . create(title=金眉毛,publishdate=年12月12日,price=100,publish=publish _ obj)
#模式2:
book _ obj=book . objects . create(title=金眉毛,publishdate=年12月12日,price=100,publish _ id=1)
核心:什么是book_obj.publish和book_obj.publish_id?
多对多
#当前生成的图书对象
book _ obj=book . objects . create(title= The Kite Runner ,price=200,publishdate=年11月12日,publish _ id=1)
#成为书籍装订的作者对象
yuan=author . objects . filter(name=袁)。first()# author表中主键为2的记录
egon=author . objects . filter(name= Alex )。first()# author表中主键为1的记录
#绑定多对多关系,即向关系表book_authors中添加记录。
Book _ obj.authors.add (yuan,egon) #在关联对象集合中添加一些特定的模型对象。=======book _ obj . authors . add(*[])
数据库记录按如下方式生成:
书桌
图书_作者表
核心:什么是book_obj.authors.all()?
用于多对多关系的其他通用API:
Book_obj.authors.remove() #从关联对象集中删除一个特定的对象。======book _ obj . authors . remove(*[])
Book_obj.authors.clear() #清空关联的对象集
Book_obj.authors.set() #在设置它之前清除它
基于对象的跨表查询一对多查询(发布和预订)正向查询(按字段:发布):
#查询主键为1的图书的出版商所在的城市。
book _ obj=book . objects . filter(PK=1)。首先()
# book_obj.publish是与主键为1的book对象相关联的出版社对象。
Print(book_obj.publish.city)反向查询(按表名:book_set):
publish=publish . objects . get(name=苹果出版社)
#publish.book_set.all():与Apple Press关联的所有book对象的集合。
book_list=publish.book_set.all()
对于book_list中的book_obj:
print(book_obj.title)
一对一查询(作者和作者详细信息)正向查询(按字段:作者详细信息):
egon=author . objects . filter(name= egon )。首先()
打印(egon.authorDetail.telephone)
反向查询(按表名:作者):
#检查地址在北京的所有作者的姓名。
author detail _ list=author detail . objects . filter(addr= Beijing )
对于authorDetail_list中的obj:
打印(对象.作者.姓名)
多对多查询(作者和图书)正向查询(按字段:作者):
#金瓶眉所有作者的姓名和手机号码
book _ obj=book . objects . filter(title=金瓶眉)first()
authors=book_obj.authors.all()
对于authors中的author_obj:
print(author_obj.name,author _ obj . author detail . telephone)
反向查询(按表名:book_set):
#检查egon出版的所有书籍的名称
author _ obj=author . objects . get(name= egon )
book _ list=author _ obj . book _ set . All()#所有与egon作者相关的书籍
对于book_list中的book_obj:
print(book_obj.title)
注意:
通过在ForeignKey()和ManyToManyField的定义中设置related_name的值,可以覆盖FOO_set的名称。例如,如果您对文章模型进行了更改:
publish=ForeignKey(Book,related_name=bookList )
那么下一步将是我们所看到的:
#查看人民出版社出版的所有书籍。
publish=publish . objects . get(name=人民出版社)
book _ list=publish . book list . all()#与人民出版社关联的所有图书对象的集合
基于双下划线的跨表查询Django还提供了一种直观高效的方式来表达查询(查找)中的关系,可以自动确认SQL JOIN连接。若要跨关系进行查询,请使用两个下划线来链接模型之间关联字段的名称,直到最终链接到所需的模型。
按字段正向查询和按表名小写反向查询用于告诉ORM引擎要连接哪个表。
一对多查询
#练习:查看苹果出版社出版的所有书籍的名称和价格(一对多)
#按字段转发查询:发布
queryResult=Book.objects。过滤器(publish__name= Apple Press )。values_list(标题,价格)
#按表名反向查询:book
queryResult=Publish.objects。过滤器(name= Apple Press )。values_list(book__title , book__price )
多对多查询
#练习:查找alex出版的所有书籍的名称(多对多)
#按字段转发查询:作者:
queryResult=Book.objects。过滤器(authors__name=袁)。值列表(标题)
#按表名反向查询:book
queryResult=Author.objects。过滤器(name=袁)。values_list(book__title , book__price )
一对一查询
#查看亚历克斯的手机号码
#正向查询
ret=author . objects . filter(name= Alex )。值(作者详细信息_ _电话)
#反向查询
ret=author detail . objects . filter(author _ _ name= Alex )。值(“电话”)
高级练习(连续跨表)
#练习:查询人民出版社出版的所有图书名称和作者姓名。
#正向查询
queryResult=Book.objects。过滤器(publish__name=人民出版社)。values_list(title , authors__name )
#反向查询
queryResult=Publish.objects。过滤器(name=人民出版社)。values_list(图书_ _标题,图书_ _作者_ _年龄,图书_ _作者_ _姓名)
#练习:手机号以151开头的作者出版的所有书籍的名称和出版社名称。
#模式1:
queryResult=Book.objects。筛选器(authors _ _ author detail _ _ telephone _ _ regex= 151 )。values_list(title , publish__name )
#模式2:
ret=作者.对象。筛选器(author detail _ _ telephone _ _ starts with= 151 )。值(图书_ _标题,图书_ _发布_ _名称)
相关名称反向查询时,如果定义了相关名称则用相关名称替换表名,例如:
publish=ForeignKey(Blog,related_name=bookList )
# 练习:查询人民出版社出版过的所有书籍的名字与价格(一对多)
# 反向查询不再按表名:书,而是相关名称:书目
queryResult=Publish.objects。过滤器(名称=人民出版社)。values_list(书目_ _标题,书目_ _价格)
聚合查询与分组查询聚合聚合(*args,**kwargs)
# 计算所有图书的平均价格
从django.db.models导入平均值
Book.objects.all().合计(平均值(价格))
{ 价格_ _平均值:34.35 }合计()是查询的一个终止子句,意思是说,它返回一个包含一些键值对的字典。键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。如果你想要为聚合值指定一个名称,可以向聚合子句提供它。
书。对象。聚合(average _ price=Avg( price ))
{ 平均价格:34.35}如果你希望生成不止一个聚合,你可以向聚合()子句中添加另一个参数。所以,如果你也想知道所有图书价格的最大值和最小值,可以这样查询:
从django.db.models导入平均值、最大值、最小值
书。对象。汇总(平均值(价格)、最大值(价格)、最小值(价格)
{price__avg: 34.35, price__max: Decimal(81.20 ), price__min: Decimal(12.99)}
分组
################################### - 单表分组查询- #######################################################
查询每一个部门名称以及对应的员工数
电磁脉冲:
身份证姓名年龄工资部门
2000年一月12日亚历克斯销售部
2埃贡22 3000人事部
3文22 5000人事部
结构化查询语言语句:
select dep,Count(*)from EMP group by dep;
ORM:
emp.objects.values(dep ).annotate(c=Count(id )
################################### - 多表分组查询- ###########################
多表分组查询:
查询每一个部门名称以及对应的员工数
电磁脉冲:
编号名称年龄薪金部门_id
一亚历克斯12 2000年一月
2埃贡22 3000 2
3文22 5000 2
资料执行防止
编号名称
一销售部
2人事部
员工-部门:
编号名称年龄薪金部门_id id名称
亚历克斯2000年12月1 1日销售部
2埃贡22 3000 2 2人事部
3文22 5000 2 2人事部
结构化查询语言语句:
select dep.name,Count(*)from EMP left join dep on EMP。dep _ id=dep。id按部门分组。编号
ORM:
dep.objetcs.values(id ).批注(c=Count(emp )).值(名称, c )
电磁脉冲类(型号。型号):
名称=型号CharField(max_length=32)
年龄=模特IntegerField()
工资=模特DecimalField(max_digits=8,decimal_places=2)
dep=模型CharField(max_length=32)
省份=车型CharField(max_length=32)视图代码
批注()为调用的查询中每一个对象都生成一个独立的统计值(统计方法用聚合函数)。
总结:跨表分组查询本质就是将关联表加入成一张表,再按单表的思路进行分组查询。
查询练习(1)练习:统计每一个出版社的最便宜的书
发布列表=发布。对象。annotate(Min price=Min( book _ _ price ))
对于出版列表中的发布对象:
print(publish_obj.name,publish_obj .MinPrice)
给…作注解的返回值是querySet,如果不想遍历对象,可以用上值列表:
queryResult=Publish.objects。annotate(Min price=Min( book _ _ price ))。values_list(name , MinPrice )
打印(查询结果)
选择应用程序01 _发布.名称,最小( app01_book .价格)"作为"应用01 _发布"中的“最低价格”
在(“应用01 _发布”)上左联接“app01_book”.nid=app01_book .publish _ id’)
按"应用01 _发布"分组 nid , app01_publish .名称, app01_publish .城市, app01_publish .电子邮件
查看代码
(2) 练习:统计每一本书的作者个数
ret=book。对象。annotate(authors num=Count( authors _ _ name )(3)统计每一本以巴拉圭开头的书籍的作者个数:
queryResult=Book.objects。过滤器(title__startswith=Py )。annotate(num _ authors=Count( authors )(4)统计不止一个作者的图书:
queryResult=Book.objects。注释(作者数量=计数(作者))。filter(num_authors__gt=1)(5)根据一本书的作者数量对查询集查询集进行排序:
book . objects . annotate(num _ authors=Count( authors ))。order_by(作者数量)
(6)查看各作者出版的图书总价:
#按作者表的所有字段分组
queryResult=Author.objects。批注(SumPrice=Sum(book__price ))。values_list(name , SumPrice )
打印(查询结果)
F-query和Q-query F-query在上面所有的例子中,我们构造的过滤器只是将字段值与一个常量进行比较。如果要比较两个字段的值,应该怎么做?
Django提供了f()来做这样的比较。f()的实例可以引用查询中的字段,以比较同一模型实例中两个不同字段的值。
#查询评论多于收藏的图书
从django.db.models导入F
book . objects . filter(commnetnum _ _ lt=f( keepnum ))Django支持f()对象之间以及f()对象与常量之间的加、减、乘、除、模运算。
#查询评论是收藏数2倍以上的书籍。
book . objects . filter(commnetnum _ _ lt=f( keepnum )* 2)还可以使用f函数进行修改操作,比如每本书提价30元:
Book.objects.all()。更新(价格=F(价格)30)
filter()等方法中关键字参数的查询是“与”在一起。如果需要执行更复杂的查询(比如OR语句),可以使用Q对象。
从django.db.models导入Q
Q(title__startswith=Py)Q对象可以与运算符结合使用。当一个操作符用于两个Q对象时,它会产生一个新的Q对象。
list=book . objects . filter(q(authors _ _ name= yuan ) q(authors _ _ name= egon ))相当于下面的SQLWHERE子句:
其中name=yuan 或name=egon 您可以组合and 运算符,并使用括号进行分组,以编写任意复杂的Q对象。同时,可以使用~运算符对Q对象求反,这允许组合普通查询和求反(非)查询:
bookList=book . objects . filter(Q(authors _ _ name= yuan )~ Q(publish date _ _ year=2017))。值列表(标题)
查询可以混合使用Q对象和关键字参数。提供给查询函数的所有参数(关键字参数或Q对象)将一起进行“与”运算。但是,如果出现Q对象,它必须在所有关键参数之前。例如:
bookList=book . objects . filter(Q(publish date _ _ year=2016) Q(publish date _ _ year=2017),
title__icontains=python
)
转载请联系作者取得转载授权,否则将追究法律责任。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。