ORM对表操作详解

表结构

  • 作者表,作者详细信息表,出版社表,书籍表

from django.db import models

# 作者表(一对一作者详细信息表)  #比较常用的信息放到这个表里面
class Author(models.Model):
name = models.CharField(max_length=32, verbose_name='作者姓名')
age = models.IntegerField(verbose_name='年龄')
# authorDetail=models.OneToOneField(to="AuthorDetail",to_field="nid",on_delete=models.CASCADE)
# #to关联表,to_field指定字段,on_delete设置级联删除
authorDetail = models.OneToOneField(to='AuthorDetail', verbose_name='作者详细信息') # 一对一到AuthorDetail表 生成为表字段之后,会自动变为authorDetail_id这样有一个名称 # OneToOneField(一对一关系) 相当于 foreign+unique
def __str__(self):
return self.name # 作者详细信息表
class AuthorDetail(models.Model):
birthday = models.DateField(verbose_name='出生日期')
# telephone=models.BigIntegerField()#不方便查询,比如模糊查询,占资源比较多
telephone = models.CharField(max_length=32, verbose_name='电话') # CharField推荐使用来存储电话
addr = models.CharField(max_length=64, verbose_name='住址') def __str__(self):
return self.addr # 出版社表 #(一对多 书籍表)是
class Publish(models.Model):
name = models.CharField(max_length=32, verbose_name='出版社名称')
city = models.CharField(max_length=32, verbose_name='出版社所在城市')
email = models.EmailField(verbose_name='出班社邮箱') # EmailField本质上是charfield做了一些邮箱规则的效验 def __str__(self):
return self.name # 书籍表
class Book(models.Model):
nid = models.AutoField(primary_key=True)
title = models.CharField(max_length=32, verbose_name='书名')
publishDate = models.DateField(verbose_name='出版日期')
price = models.DecimalField(max_digits=5, decimal_places=2,
verbose_name='价格') # max_digits小数总位数,decimal_places小数部分位数
publishs = models.ForeignKey(to="Publish", verbose_name='出版社')
authors = models.ManyToManyField(to='Author', verbose_name='作者') def __str__(self):
return self.title

ORM对表的 增 删 改 查

  • 增加

一对一
models.Author.objects.create(name='xx',age=18,authorDetail=mdoels.AuthorDetail.Objects.get(id=1))
models.Author.objects.create(name='xx',age=18,authorDetail_id=2) 一对多
models.Book.objects.create(xx=xx,publishs=mdoels.Publish.Objects.get(id=1))
models.Book.objects.create(xx=xx,publishs_id=2) 多对多
book_obj = models.Book.objects.get(id=1)
book_obj.authors.add(*[author_obj1,author_obj2,..])
book_obj.authors.add(*[1,2,3...])
一对一
models.Author.objects.filter(id=1).delete()
一对多
models.Book.objects.filter(id=1).delete()
多对多
book_obj = models.Book.objects.get(id=1)
book_obj.authors.remove(1,2,3,4)
book_obj.authors.remove(*[1,2,...]) book_obj.authors.clear() book_obj.authors.set(['1','2',...]) :clear -- add
一对一
models.Author.objects.filter(id=1).update(
authorDetail=mdoels.AuthorDetail.Objects.get(id=1)
)
models.Author.objects.filter(id=1).update(
authorDetail_id=2,
)
一对多
models.Book.objects.filter(id=1).update(
publishs=mdoels.Publish.Objects.get(id=1)
)
models.Book.objects.filter(id=1).update(
publishs_id=2,
) 多对多
book_obj.authors.set(['1','2',...]) :clear -- add

基于对象的跨表查询 -- 类似于子查询

  • 正向查询和反向查询

  • 关系属性(字段)写在哪个类(表)里面,从当前类(表)的数据去查询它关联类(表)的数据叫做正向查询,反之叫做反向查询

#查询
# 一对一
# 正向查询
#1 查询崔老师的电话号
# author_obj = models.Author.objects.filter(name='崔老师').first()
# # print(author_obj.authorDetail) #辽宁峨眉山
# # print(author_obj.authorDetail.telephone) #444
# #2 反向查询
# #2 查询一下这个444电话号是谁的.
# author_detail_obj = models.AuthorDetail.objects.get(telephone='444')
# print(author_detail_obj.author) #崔老师
# print(author_detail_obj.author.name) #崔老师 ''' 正向查询:Authorobj.authorDetail,对象.关联属性名称
Author----------------------------------->AuthorDetail
<-----------------------------------
反向查询:AuthorDetailobj.author ,对象.小写类名
''' # 一对多
# 查询一下李帅的床头故事这本书的出版社是哪个
# 正向查询
book_obj = models.Book.objects.get(title='李帅的床头故事')
print(book_obj.publishs) #B哥出版社
print(book_obj.publishs.name) #B哥出版社 # B哥出版社出版社出版了哪些书
# 反向查询
pub_obj = models.Publish.objects.get(name='B哥出版社')
print(pub_obj.book_set.all()) #<QuerySet [<Book: 李帅的床头故事>, <Book: 李帅的床头故事2>]> ''' 正向查询 book_obj.publishs 对象.属性
Book ---------------------------------------------> Publish
<----------------------------------------------
反向查询 publish_obj.book_set.all() 对象.表名小写_set
''' # 多对多
# 李帅的床头故事这本书是谁写的
# 正向查询
book_obj = models.Book.objects.get(title='李帅的床头故事')
print(book_obj.authors.all())
# 高杰写了哪些书
author_obj = models.Author.objects.get(name='高杰')
print(author_obj.book_set.all()) ''' 正向查询 book_obj.authors.all() 对象.属性
Book ---------------------------------------------> Author
<----------------------------------------------
反向查询 author_obj.book_set.all() 对象.表名小写_set
'''

基于双下划的跨表查询 -- 连表 join

  • 正向查询和反向查询
#查询
# 一对一
# 1. 查询崔老师的电话号
# 方式1 正向查询
# obj = models.Author.objects.filter(name='崔老师').values('authorDetail__telephone')
# print(obj) #<QuerySet [{'authorDetail__telephone': '444'}]>
# 方式2 反向查询
# obj = models.AuthorDetail.objects.filter(author__name='崔老师').values('telephone','author__age')
# print(obj) #<QuerySet [{'telephone': '444'}]>
# 2. 哪个老师的电话是444
# 正向
# obj = models.Author.objects.filter(authorDetail__telephone='444').values('name')
# print(obj)
# 反向
# obj = models.AuthorDetail.objects.filter(telephone='444').values('author__name')
# print(obj) # 一对多
# 查询一下李帅的床头故事这本书的出版社是哪个
# obj = models.Book.objects.filter(title='李帅的床头故事').values('publishs__name')
# print(obj) #<QuerySet [{'publishs__name': 'B哥出版社'}]> # obj = models.Publish.objects.filter(book__title='李帅的床头故事').values('name')
# obj = models.Publish.objects.filter(xx__title='李帅的床头故事').values('name')
# print(obj) # B哥出版社出版社出版了哪些书
# obj = models.Publish.objects.filter(name='B哥出版社').values('book__title')
# print(obj) #<QuerySet [{'book__title': '李帅的床头故事'}, {'book__title': '李帅的床头故事2'}]> # obj = models.Book.objects.filter(publishs__name='B哥出版社').values('title')
# print(obj) #<QuerySet [{'title': '李帅的床头故事'}, {'title': '李帅的床头故事2'}]> # 李帅的床头故事这本书是谁写的
# obj = models.Book.objects.filter(title='李帅的床头故事').values('authors__name')
# print(obj)
# obj = models.Author.objects.filter(book__title='李帅的床头故事').values('name')
# print(obj) #<QuerySet [{'name': '高杰'}, {'name': '崔老师'}]> #高杰写了哪些书
# obj = models.Book.objects.filter(authors__name='高杰').values('title')
# print(obj)
# obj = models.Author.objects.filter(name='高杰').values('book__title')
# print(obj) #进阶的
# B哥出版社 出版的书的名称以及作者的名字
# obj = models.Book.objects.filter(publishs__name='B哥出版社').values('title','authors__name')
# print(obj)
#<QuerySet [{'title': '李帅的床头故事', 'authors__name': '高杰'}, {'title': '李帅的床头故事', 'authors__name': '崔老师'}, {'title': '李帅的床头故事2', 'authors__name': '崔老师'}, {'title': '李帅的床头故事2', 'authors__name': '王涛'}]>
'''
SELECT app01_book.title,app01_author.name from app01_publish INNER JOIN app01_book on app01_publish.id=app01_book.publishs_id
INNER JOIN app01_book_authors on app01_book.nid = app01_book_authors.book_id INNER JOIN app01_author
ON app01_author.id = app01_book_authors.author_id where app01_publish.name='B哥出版社';
:param request:
:return:
''' # obj = models.Publish.objects.filter(name='B哥出版社').values('book__title','book__authors__name')
# print(obj) # obj = models.Author.objects.filter(book__publishs__name='B哥出版社').values('name','book__title')
# print(obj) # authorDetail author book publish
# 手机号以4开头的作者出版过的所有书籍名称以及出版社名称
# ret = models.AuthorDetail.objects.filter(telephone__startswith='4').values('author__book__title','author__book__publishs__name')
# print(ret)
#QuerySet [{'author__book__title': '李帅的床头故事', 'author__book__publishs__name': 'B哥出版社'}, {'author__book__title': '李帅的床头故事2', 'author__book__publishs__name': 'B哥出版社'}]> #查询一下B哥出版社出版了哪些书
# obj = models.Publish.objects.filter(name='B哥出版社').first()
# print(obj.xx.all())

ORM对表的操作示例

操作示例 点击查看(代码)

System.out.println("Hello to see U!");
```python
1.1 一对一增加
new_author_detail = models.AuthorDetail.objects.create(
birthday='1979-08-08',
telephone='138383838',
addr='黑龙江哈尔滨'
)
obj = models.AuthorDetail.objects.filter(addr='山西临汾').first()
方式1
models.Author.objects.create(
name='王涛',
age='40',
authorDetail=new_author_detail,
) 方式2 常用
models.Author.objects.create(
name='王涛',
age='40',
authorDetail_id=obj.id,
) 1.2 一对多增加
方式1
obj = models.Publish.objects.get(id=2)
models.Book.objects.create(
title = '李帅的床头故事',
publishDate='2019-07-22',
price=3,
# publishs=models.Publish.objects.get(id=1),
publishs=obj,
) 方式2 常用
models.Book.objects.create(
title='李帅的床头故事2',
publishDate='2019-07-21',
price=3.5,
# publishs=models.Publish.objects.get(id=1),
publishs_id=obj.id
) 1.3 多对多增加
方式1 常用(效率高)
book_obj = models.Book.objects.get(nid=1)
book_obj.authors.add(*[1,2]) 方式2
author1 = models.Author.objects.get(id=1)
author2 = models.Author.objects.get(id=3)
book_obj = models.Book.objects.get(nid=5)
book_obj.authors.add(*[author1,author2])

### ORM对表的 删 操作 ```python
#一对一 和 一对多 的删除和单表删除是一样的.
#一对一 表一外键关联到表二,表一删除,不影响表2,表2删除会影响表1
models.AuthorDetail.objects.get(id=2).delete()
models.Author.objects.get(id=3).delete() 一对多
models.Publish.objects.get(id=1).delete()
models.Book.objects.get(nid=1).delete() 多对多关系删除
book_obj = models.Book.objects.get(nid=6)
book_obj.authors.remove(6) #authors是表中的关联对象 删除单个
book_obj.authors.remove(*[5,6]) #删除多个
book_obj.authors.clear() #全部关联对象删除
book_obj.authors.add(*[1,]) #添加
book_obj.authors.set('1') #删除之前关系添加新关系
book_obj.authors.set(['5','6']) #删除然后更新 多个

ORM对表的 更新 操作

    一对一 更新
models.Author.objects.filter(id=5).update(
name='崔老师',
age=16,
# authorDetail=models.AuthorDetail.objects.get(id=5),
authorDetail_id=4,
) 一对多 更新
models.Book.objects.filter(pk=4).update(
title='B哥的往事2',
# publishs=models.Publish.objects.get(id=3),
publishs_id=3,
) #一对多
models.Publish.objects.filter(pk=2).update(
id=4, # 没有级联更新,报错!!
)

ORM对表的 查询 操作(重点 )

#查询
# 一对一
# 1. 查询崔老师的电话号
# 方式1 正向查询
# obj = models.Author.objects.filter(name='崔老师').values('authorDetail__telephone')
# print(obj) #<QuerySet [{'authorDetail__telephone': '444'}]> #方式2 反向查询
# obj = models.AuthorDetail.objects.filter(author__name='崔老师').values('telephone','author__age')
# print(obj) #<QuerySet [{'telephone': '444'}]> # 2. 哪个老师的电话是444
# 正向
# obj = models.Author.objects.filter(authorDetail__telephone='444').values('name')
# print(obj)
# 反向
# obj = models.AuthorDetail.objects.filter(telephone='444').values('author__name')
# print(obj) # 一对多
# 查询一下李帅的床头故事这本书的出版社是哪个
# obj = models.Book.objects.filter(title='李帅的床头故事').values('publishs__name')
# print(obj)
# obj = models.Publish.objects.filter(book__title='李帅的床头故事').values('name')
# print(obj)
# B哥出版社出版社出版了哪些书
# obj = models.Publish.objects.filter(name='B哥出版社').values('book__title')
# print(obj) #<QuerySet [{'book__title': '李帅的床头故事'}, {'book__title': '李帅的床头故事2'}]> # obj = models.Book.objects.filter(publishs__name='B哥出版社').values('title')
# print(obj) #<QuerySet [{'title': '李帅的床头故事'}, {'title': '李帅的床头故事2'}]> # 李帅的床头故事这本书是谁写的
# obj = models.Book.objects.filter(title='李帅的床头故事').values('authors__name')
# print(obj)
# obj = models.Author.objects.filter(book__title='李帅的床头故事').values('name')
# print(obj) #<QuerySet [{'name': '高杰'}, {'name': '崔老师'}]> # 高杰写了哪些书
# obj = models.Book.objects.filter(authors__name='高杰').values('title')
# print(obj)
# obj = models.Author.objects.filter(name='高杰').values('book__title')
# print(obj) # 进阶的
# B哥出版社 出版的书的名称以及作者的名字
# obj = models.Book.objects.filter(publishs__name='B哥出版社').values('title','authors__name')
# print(obj)
# <QuerySet [{'title': '李帅的床头故事', 'authors__name': '高杰'}, {'title': '李帅的床头故事', 'authors__name': '崔老师'}, {'title': '李帅的床头故事2', 'authors__name': '崔老师'}, {'title': '李帅的床头故事2', 'authors__name': '王涛'}]>
'''
SELECT app01_book.title,app01_author.name from app01_publish INNER JOIN app01_book on app01_publish.id=app01_book.publishs_id
INNER JOIN app01_book_authors on app01_book.nid = app01_book_authors.book_id INNER JOIN app01_author
ON app01_author.id = app01_book_authors.author_id where app01_publish.name='B哥出版社';
:param request:
:return:
''' # obj = models.Publish.objects.filter(name='B哥出版社').values('book__title','book__authors__name')
# print(obj) # obj = models.Author.objects.filter(book__publishs__name='B哥出版社').values('name','book__title')
# print(obj) # authorDetail author book publish
# 手机号以4开头的作者出版过的所有书籍名称以及出版社名称
# ret = models.AuthorDetail.objects.filter(telephone__startswith='4').values('author__book__title','author__book__publishs__name')
# print(ret)
# QuerySet [{'author__book__title': '李帅的床头故事', 'author__book__publishs__name': 'B哥出版社'}, {'author__book__title': '李帅的床头故事2', 'author__book__publishs__name': 'B哥出版社'}]> # 查询一下B哥出版社出版了哪些书
# obj = models.Publish.objects.filter(name='B哥出版社').first()
# print(obj.xx.all())

正向查 与 反向查

  • 正向查反向查(从设置表关系的那张表查另一张就是正向,反之就是反向查)

related_name 给反向查询的小写表名起别名,以后反向查询调用都用这个别名

作 者:郭楷丰
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角 推荐一下。您的鼓励是博主的最大动力!
自 勉:生活,需要追求;梦想,需要坚持;生命,需要珍惜;但人生的路上,更需要坚强。带着感恩的心启程,学会爱,爱父母,爱自己,爱朋友,爱他人。

ORM 对表操作 详解的更多相关文章

  1. Django框架 之 ORM查询操作详解

    Django框架 之 ORM查询操作详解 浏览目录 一般操作 ForeignKey操作 ManyToManyField 聚合查询 分组查询 F查询和Q查询 事务 Django终端打印SQL语句 在Py ...

  2. Golang beego ORM + CRUP 操作详解

      构建beego Web 项目         首先构建一个beego 的web 项目,这个我们完全可以参考beego 官网中的开发文档,上面介绍的非常的详细,在这我就不给大家介绍,主要是介绍ORM ...

  3. Django之ORM查询操作详解

    浏览目录 一般操作 ForeignKey操作 ManyToManyField 聚合查询 分组查询 F查询和Q查询 事务 Django终端打印SQL语句 在Python脚本中调用Django环境 其他操 ...

  4. python/ORM操作详解

    一.python/ORM操作详解 ===================增==================== models.UserInfo.objects.create(title='alex ...

  5. [Android新手区] SQLite 操作详解--SQL语法

    该文章完全摘自转自:北大青鸟[Android新手区] SQLite 操作详解--SQL语法  :http://home.bdqn.cn/thread-49363-1-1.html SQLite库可以解 ...

  6. MySQL 操作详解

    MySQL 操作详解 一.实验简介 本节实验中学习并实践 MySQL 上创建数据库.创建表.查找信息等详细的语法及参数使用方法. 二.创建并使用数据库 1. 创建并选择数据库 使用SHOW语句找出服务 ...

  7. Linq实战 之 Linq to Sql及Entity Framework操作详解

    Linq实战 之 Linq to Sql及Entity Framework操作详解 一:linq to db的框架 1. linq to sql 2. linq to ado.net entity f ...

  8. django ORM 外键详解

    Django中的外键: 首先,为了方便理解,我们把使用ForeignKey的字段所在的表定义为从表,把ForeignKey中to参数连接的表称为主表. 外键使用的先决条件: 在mysql数据表中,数据 ...

  9. MongoDB各种查询操作详解

    这篇文章主要介绍了MongoDB各种查询操作详解,包括比较查询.关联查询.数组查询等,需要的朋友可以参考下   一.find操作 MongoDB中使用find来进行查询,通过指定find的第一个参数可 ...

随机推荐

  1. @MatrixVariable的使用

    @MatrixVariable的使用 博客分类: J2EE   在Spring3.2 后,一个@MatrixVariable出现了,这个注解的出现拓展了URL请求地址的功能. Matrix Varia ...

  2. 使用协方差矩阵的特征向量PCA来处理数据降维

    取2维特征,方便图形展示 import matplotlib.pyplot as plt from sklearn.decomposition import PCA from sklearn.data ...

  3. [Kaggle] Online Notebooks

    前言 Let's go to https://www.kaggle.com/ Kaggle Notebook 有实践记录的案例. 一.线性拟合噪声数据 [Sklearn] Linear regress ...

  4. springboot 整合mongodb

    Mongodb Mongodb是为快速开发互联网Web应用而构建的数据库系统,其数据模型和持久化策略就是为了构建高读/写吞吐量和高自动灾备伸缩性的系统. 在pom.xml中添加相关依赖 <!-- ...

  5. BUG处理流程图

    流程描述: 1. 测试人员发现bug提交给开发. 2. 开发人员判断是否是bug. 3. 如果是bug,进行修改,修改完成后更改bug状态为已解决. 4. 如果不是bug,退回给测试人员并描述退回原因 ...

  6. 解决在manjaro下,vscode无法将chrome作为默认浏览器打开

    Same issue. The solution is simple. Find the name of the exec command, for google chrome in arch lin ...

  7. 编写max(list) 返回列表最大元素

    defmodule MyList do def max(list), do: _max(list, 0) defp _max([], max), do: max defp _max([head | t ...

  8. python测试工具nosetests

    今天在github上找东西,找到个工具是python写的,但是需要安装nosetests,因此了解了下nosetests python除了unittest,还有nosetests,使用更快捷 nose ...

  9. Spring Boot拦截器实现并和swagger集成后使用拦截器的配置问题

    1. 定义拦截器 LoginInterceptor LoginInterceptor.java是整个登录认证模块中的核心类之一,它实现了HandlerInterceptor类,由它来拦截并过滤到来的每 ...

  10. SpringBoot2+Druid+JdbcTemplate+MySql实现增删改查

    1.配置pom.xml文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&qu ...