Django中模型层中ORM的多表操作

2023-10-19 08:30

本文主要是介绍Django中模型层中ORM的多表操作,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

ORM的多表创建(一对一.一对多,多对多):

1模型创建

  实例:我们来假定下面这些概念,字段和关系

作者模型:一个作者有姓名和年龄。

作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息。作者详情模型和作者模型之间是一对一的关系(one-to-one)

出版商模型:出版商有名称,所在城市以及email。

书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many);一本书只应该由一个出版商出版,所以出版商和书籍是一对多关联关系(one-to-many)。

模型建立如下:

from django.db import models# Create your models here.class Book(models.Model):id = models.AutoField(primary_key=True)  # 可不填,Django会自动帮你写title = models.CharField(max_length=32)pub_date = models.DateField()price = models.DecimalField(max_digits=5, decimal_places=2)# 与Publish(id)建立一对多的外键关系publish = models.ForeignKey(to="Publish", to_field="id", on_delete=models.CASCADE)# 创建多对多的关系,不会添加外键,会另外创建表格authors = models.ManyToManyField(to="Author")def __str__(self):return self.titleclass Publish(models.Model):name = models.CharField(max_length=32)city = models.CharField(max_length=32)email = models.EmailField()def __str__(self):return self.nameclass Author(models.Model):name = models.CharField(max_length=32)age = models.IntegerField()# 与authorDetail建立一对一的外键关系authorDetail = models.OneToOneField(to="AuthorDetail", on_delete=models.CASCADE)def __str__(self):return self.nameclass AuthorDetail(models.Model):birthday = models.DateField()phone = models.BigIntegerField()addr = models.CharField(max_length=64)def __str__(self):return self.addrclass Emp(models.Model):name = models.CharField(max_length=32)age = models.IntegerField()salary = models.DecimalField(max_digits=8, decimal_places=2)dep = models.CharField(max_length=32)province = models.CharField(max_length=32)def __str__(self):return self.nameclass Article(models.Model):title = models.CharField(max_length=32)comment_num = models.IntegerField()poll_num = models.IntegerField()def __str__(self): return self.title
View Code

注意事项:

  •  表的名称myapp_modelName,是根据 模型中的元数据自动生成的,也可以覆写为别的名称  
  •  id 字段是自动添加的
  •  对于外键字段,Django 会在字段名上添加"_id" 来创建数据库中的列名
  •  这个例子中的CREATE TABLE SQL 语句使用PostgreSQL 语法格式,要注意的是Django 会根据settings 中指定的数据库类型来使用相应的SQL 语句。
  •  定义好模型之后,你需要告诉Django _使用_这些模型。你要做的就是修改配置文件中的INSTALL_APPSZ中设置,在其中添加models.py所在应用的名称。
  • 外键字段 ForeignKey 有一个 null=True 的设置(它允许外键接受空值 NULL),你可以赋给它空值 None 。

2.多表记录的操作

2.1 多表操作之表记录的创建

  2.1.1一对一以及一对多记录的创建:

1  方式一
2     book = models.Book.objects.create(title="java",price=122,pub_date="2012-02-12",publish_id=1)
3 
4     方式二
5     pub_obj = models.Publish.objects.filter(name="西瓜出版社").first()
6     book = models.Book.objects.create(title="PHP", price=122, pub_date="2014-02-12", publish = pub_obj)
7     print(book.title)
8     print(book.publish_id)
View Code

  2.1.2 多对多记录的创建

 ######################### 绑定多对多的关系;无非是在关系表创建记录 ##########################
    tips: 正向操作按字段,反向操作按表名小写(一定要记住)为java这本书绑定两个作者: 大锤,尼玛(正向绑定):添加方式一java = models.Book.objects.filter(title="java").first()dachui = models.Author.objects.filter(name="王大锤").first()nima =  models.Author.objects.filter(name="王尼玛").first()print(java.price)print(dachui.name)print(nima.name)java.authors.add(dachui,nima)添加方式二java.authors.add(2)java.authors.add(*[3,2])   #添加的另外一种方式,较常用,[]内为对应作者的ID,*用于打散
移除两个作者与java的绑定关系java.authors.remove(dachui, nima) # 将某个特定的对象从被关联对象集合中去除。== book_obj.authors.remove(*[])
java.authors.clear() #清空被关联对象集合
重新赋值关系java.authors.set([3,])  #重新设置值,先clear,在赋值
给王大锤作者绑定两本书籍: PHP,Go(反向绑定)dachui = models.Author.objects.filter(name="王大锤").first()PHP = models.Book.objects.filter(title="PHP").first()Go = models.Book.objects.filter(title="Go").first()方式一:dachui.book_set.add(PHP, Go)   ###此处因为是反向绑定采用的是 表名_set
    方式二dachui.book_set.add(*[3,4])
View Code

 

2.2多表操作之跨表查询

 

2.2.1基于对象的跨表查询

  总的查询思路

  一 基于对象的跨表查询( 子查询:以上一次的查询结果作为下一次的查询条件)(1)一对多正向查询:按字段 book.publishBook对象    ---------------------------------- >  Publish 对象<---------------------------------反向查询:按表名小写_set.all()(2)多对多正向查询:按字段 book.authors.all()Book对象    ---------------------------------- >  Author 对象<---------------------------------反向查询:按表名小写_set.all()(2)一对一正向查询:按字段 book.adAuthor 对象   ---------------------------------- >  AuthorDetail 对象<---------------------------------反向查询:按表名小写

 

  2.2.1.1 基于对象的一对多的跨表查询

(1)一对多1 查询PHP这本书籍的出版社的地址(正向查询)addr = models.Book.objects.filter(title="PHP").first().publish.cityprint(addr)2 查询香蕉出版社出版的所有书籍(反向查询)queryset = models.Publish.objects.filter(name="西瓜出版社").first().book_set.all()print(queryset)
View Code

  2.2.1.2 基于对象的多对多的跨表查询

 (2)多对多1 查询java书籍的所有作者queryset = models.Book.objects.filter(title="java").first().authors.all()print(queryset)2 查询王大锤作者出版过得所有书籍queryset = models.Author.objects.filter(name="王大锤").first().book_set.all()print(queryset)
View Code

  2.2.1.3 基于对象的一对一的跨表查询

(3)一对一1  查询王大锤的手机号phone = models.Author.objects.filter(name="王大锤").first().authorDetail.phoneprint(phone)2 查询手机号为123的作者的名字name = models.AuthorDetail.objects.filter(phone="123").first().author.nameprint(name)
View Code

 

2.2.2  基于双下划綫的跨表查询:
 KEY: 通知ORM引擎如何跨表: 正向查询按字段, 反向查询按表名小写

2.2.2.1基于双下划线的跨表查询(join查询)

 ################基于双下划线的跨表查询(join查询)##########################1 查询PHP这本书籍的出版社的地址'''SELECT app01_publish.city from app01_book INNER JOIN app01_publish ON app01_book.publish_id = app01_publish.id WHERE app01_book.title ="PHP"'''
方式1queryset_addr = models.Book.objects.filter(title="PHP").values("publish__city")print(queryset_addr)方式2queryset_addr = models.Publish.objects.filter(book__title="PHP").values("city")print(queryset_addr)2 查询java书籍的所有作者queryset_author = models.Book.objects.filter(title="java").values("authors__name")queryset_author = models.Book.objects.filter(title__startswith="P").values("authors__name")print(queryset_author)3  查询唐马儒的手机号queryset_tel = models.Author.objects.filter(name="唐马儒").values("authorDetail__phone")queryset_tel = models.AuthorDetail.objects.filter(author__name="唐马儒").values("phone")print(queryset_tel)
View Code

2.2.2.2 连续跨表操作及其示例:

连续跨表4 查询西瓜出版社出版过的所有书籍的名字以及作者的姓名queryset_info = models.Book.objects.filter(publish__name="西瓜出版社").values("title","authors__name")queryset_info = models.Author.objects.filter(book__publish__name="西瓜出版社").values("book__title","name")print(queryset_info)5 手机号以151开头的作者出版过的所有书籍名称以及出版社名称queryset_info = models.Book.objects.filter(authors__authorDetail__phone__startswith="1").values("title","publish__name")print(queryset_info
View Code

 

2.2.3  聚合查询:
1 ######################聚合查询#############################3
2     aggregate()
3 
4     from django.db.models import Avg,Max,Min,Count
5     1.计算所有人的平均工资
6     ret = models.Emp.objects.all().aggregate(平均工资=Avg("salary"))
7     print(re

 

2.2.4  单表分组查询:
    ############## 单表分组查询  ###############
查询每一个部门的人数ret = models.Emp.objects.values("dep").annotate(Count("id"))查询省份名字有东的部门的人数ret = models.Emp.objects.filter(province__contains="").values("dep").annotate(c = Count("id"))print(ret)# 查询每一个省份的平均薪水ret = models.Emp.objects.values("province").annotate(avg_salary=Avg("salary"))print(ret)

 

2.2.4  多表分组查询:
############## 多表分组查询  ###############1 查询每一个出版社的名字和出版过的书籍的平均价格querryset = models.Publish.objects.values("name").annotate(avg_salary=Avg("book__price"))querryset = models.Publish.objects.annotate(avg_salary=Avg("book__price")).values("name","avg_salary")print(querryset)2 查询每一个作者的名字以及出版书籍的个数querryset = models.Author.objects.values("name").annotate(c = Count("book__id"))querryset = models.Author.objects.annotate(c = Count("book__id")).values("name","c")print(querryset)3 查询每一个书籍的名称以及作者的个数querryset = models.Book.objects.values("title").annotate(c = Count("authors__id"))print(querryset)4 查询作者个数大于1 的每一本书籍的名称和作者个数querryset = models.Book.objects.annotate(c = Count("authors__id")).filter(c__gt=1).values("title","c")print(querryset)5 查询书籍名称包含"h"的书籍名称和作者个数querryset = models.Book.objects.filter(title__contains="P").annotate(c = Count("authors__id")).values("title","c")querryset = models.Book.objects.annotate(c=Count("authors__id")).filter(title__contains="P").values("title", "c")print(querryset)

 

2.2.4  F与Q查询:

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

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

 

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

 

##################################### F查询与Q查询
F查询from django.db.models import F,Q,Avg1 查询评论数大于100的文章ret = models.Article.objects.filter(comment_num__gt=300)print(ret)2 查询评论数大于点赞数的文章ret = models.Article.objects.filter(comment_num__gt=F("poll_num"))print(ret)3 查询评论数大于两倍点赞数ret = models.Article.objects.filter(comment_num__gt = F("poll_num")*2)print(ret)4 将所有的书籍的价格提高100元ret = models.Book.objects.update(price = F("price")+10)print(ret)Q查询5 查询价格大于300或者名称以p开头的书籍Q : & | ~ret = models.Book.objects.filter(Q(price__gt=150)|Q(title__startswith="P"))print(ret)# 5 查询价格大于300或者不是2012年2月份的书籍ret = models.Book.objects.filter(Q(price__gt=140) | Q(Q(pub_date__year=2012)&Q(pub_date__month=2)))ret = models.Book.objects.filter(Q(price__gt=140) | Q(pub_date__year=2012) & Q(pub_date__month=2))ret = models.Book.objects.filter(Q(price__gt=140) | Q(pub_date__year=2012,pub_date__month=2))print(ret)
View Code

 

详细请参考:ORM多表查询

 

 

转载于:https://www.cnblogs.com/Mixtea/p/10469839.html

这篇关于Django中模型层中ORM的多表操作的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/238618

相关文章

RedHat运维-Linux文本操作基础-AWK进阶

你不用整理,跟着敲一遍,有个印象,然后把它保存到本地,以后要用再去看,如果有了新东西,你自个再添加。这是我参考牛客上的shell编程专项题,只不过换成了问答的方式而已。不用背,就算是我自己亲自敲,我现在好多也记不住。 1. 输出nowcoder.txt文件第5行的内容 2. 输出nowcoder.txt文件第6行的内容 3. 输出nowcoder.txt文件第7行的内容 4. 输出nowcode

一份LLM资源清单围观技术大佬的日常;手把手教你在美国搭建「百万卡」AI数据中心;为啥大模型做不好简单的数学计算? | ShowMeAI日报

👀日报&周刊合集 | 🎡ShowMeAI官网 | 🧡 点赞关注评论拜托啦! 1. 为啥大模型做不好简单的数学计算?从大模型高考数学成绩不及格说起 司南评测体系 OpenCompass 选取 7 个大模型 (6 个开源模型+ GPT-4o),组织参与了 2024 年高考「新课标I卷」的语文、数学、英语考试,然后由经验丰富的判卷老师评判得分。 结果如上图所

大语言模型(LLMs)能够进行推理和规划吗?

大语言模型(LLMs),基本上是经过强化训练的 n-gram 模型,它们在网络规模的语言语料库(实际上,可以说是我们文明的知识库)上进行了训练,展现出了一种超乎预期的语言行为,引发了我们的广泛关注。从训练和操作的角度来看,LLMs 可以被认为是一种巨大的、非真实的记忆库,相当于为我们所有人提供了一个外部的系统 1(见图 1)。然而,它们表面上的多功能性让许多研究者好奇,这些模型是否也能在通常需要系

人工和AI大语言模型成本对比 ai语音模型

这里既有AI,又有生活大道理,无数渺小的思考填满了一生。 上一专题搭建了一套GMM-HMM系统,来识别连续0123456789的英文语音。 但若不是仅针对数字,而是所有普通词汇,可能达到十几万个词,解码过程将非常复杂,识别结果组合太多,识别结果不会理想。因此只有声学模型是完全不够的,需要引入语言模型来约束识别结果。让“今天天气很好”的概率高于“今天天汽很好”的概率,得到声学模型概率高,又符合表达

SQL Server中,always on服务器的相关操作

在SQL Server中,建立了always on服务,可用于数据库的同步备份,当数据库出现问题后,always on服务会自动切换主从服务器。 例如192.168.1.10为主服务器,12为从服务器,当主服务器出现问题后,always on自动将主服务器切换为12,保证数据库正常访问。 对于always on服务器有如下操作: 1、切换主从服务器:假如需要手动切换主从服务器时(如果两个服务

智能客服到个人助理,国内AI大模型如何改变我们的生活?

引言 随着人工智能(AI)技术的高速发展,AI大模型越来越多地出现在我们的日常生活和工作中。国内的AI大模型在过去几年里取得了显著的进展,不少独创的技术点和实际应用令人瞩目。 那么,国内的AI大模型有哪些独创的技术点?它们在实际应用中又有哪些出色表现呢?此外,普通人又该如何利用这些大模型提升工作和生活的质量和效率呢?本文将为你一一解析。 一、国内AI大模型的独创技术点 多模态学习 多

JavaWeb系列二十: jQuery的DOM操作 下

jQuery的DOM操作 CSS-DOM操作多选框案例页面加载完毕触发方法作业布置jQuery获取选中复选框的值jQuery控制checkbox被选中jQuery控制(全选/全不选/反选)jQuery动态添加删除用户 CSS-DOM操作 获取和设置元素的样式属性: css()获取和设置元素透明度: opacity属性获取和设置元素高度, 宽度: height(), widt

OpenCompass:大模型测评工具

大模型相关目录 大模型,包括部署微调prompt/Agent应用开发、知识库增强、数据库增强、知识图谱增强、自然语言处理、多模态等大模型应用开发内容 从0起步,扬帆起航。 大模型应用向开发路径:AI代理工作流大模型应用开发实用开源项目汇总大模型问答项目问答性能评估方法大模型数据侧总结大模型token等基本概念及参数和内存的关系大模型应用开发-华为大模型生态规划从零开始的LLaMA-Factor

模型压缩综述

https://www.cnblogs.com/shixiangwan/p/9015010.html

PS的一些操作~持续抄袭中....

套索工具使用时移动图片——按住空格键,鼠标左键按住,拖动!