django orm操作,

  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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: