单表多表操作

rongge95500 rongge95500     2023-01-26     658

关键词:

一、单表操作

1.1 在python的脚本下调用Django环境

技术分享图片test.py

1.2 用orm创建表

技术分享图片models.py
  • 数据的迁移操作
python3 manage.py makemigrations    #只是对变化做一个记录,记录文件在app的migrations文件夹下
python3 manage.py migrate        #把更改提交到数据库
python3 manage.py showmigrations    #查看那个app中的数据没有提交到数据库,打×表示已提交

1.3 对数据的操作

  • 添加数据
# 方法一:
models.Book.objects.create(name=‘阿甘正传‘, price=‘23‘, publish=‘环球出版社‘, date=‘2018-8-8‘)

# 方法二:
import datetime
c_time = datetime.datetime.now()
book = models.Book(name=‘史前人类‘, price=‘68‘, publish=‘华夏出版社‘, date=c_time)
book.save()
  • 删除数据
# 方法一:
models.Book.objects.filter(name=‘史前人类‘).delete()

# 方法二:
book = models.Book.objects.filter(name=‘史前人类‘).first()
book.delete(
  • 修改数据
# 方法一:
book = models.Book.objects.filter(name=‘阿甘正传‘).update(price=‘44‘)

# 方法二:
book = models.Book.objects.filter(name=‘阿甘正传‘).first()
book.price = ‘55‘
book.save()
  • 查询数据
1> all():                  查询所有结果                   
2> filter(**kwargs):       它包含了与所给筛选条件相匹配的对象      
3> get(**kwargs):          返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。 
4> exclude(**kwargs):      它包含了与所给筛选条件不匹配的对象 
5> order_by(*field):       对查询结果排序(‘-id‘)   
6> reverse():              对查询结果反向排序         
7> count():                返回数据库中匹配查询(QuerySet)的对象数量。   
8> first():                返回第一条记录      
9> last():                 返回最后一条记录        
10> exists():              如果QuerySet包含数据,就返回True,否则返回False    
11> values(*field):        返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列 model的实例化对象,而是一个可迭代的字典序列
12> values_list(*field):   它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列           
13> distinct():            从返回结果中剔除重复纪录
# 补充:对象.query,可查看查询的sql语句
# .all()
book = models.Book.objects.all()

# .filter()
book = models.Book.objects.filter(name=‘孝庄秘史‘)

# .get(**kwargs) 有且只有一个结果时才能用,如果有一个,返回的是对象,不是queryset对象,通常用在,用id查询的情况
book = models.Book.objects.get(name=‘阿甘正传‘)
# name: 阿甘正传, price: 55

# .exclude(**kwargs) 除了符合条件的结果,结果也是queryset对象
book = models.Book.objects.exclude(name=‘神秘的西夏王陵‘)

# .order_by()
# 按价格升序排序
book = models.Book.objects.all().order_by(‘price‘)
# 按价格降序排序
book = models.Book.objects.all().order_by(‘-price‘)
# 其后可继续跟筛选条件
book = models.Book.objects.all().order_by(‘price‘).filter(name=‘阿甘正传‘)

# .reverse() 将查询结果进行反向排序
book = models.Book.objects.all().order_by(‘price‘).reverse()

# .count() 查询结果的个数
book = models.Book.objects.filter(name=‘阿甘正传‘).count()

# .last() 多个结果时返回最后一个
book = models.Book.objects.filter(name=‘阿甘正传‘).last()

# .exists() 返回的是结果的布尔值
book = models.Book.objects.filter(name=‘阿甘正传‘).exists()

# .values() queryset对象里套字典
book = models.Book.objects.all().values(‘name‘)
# < QuerySet[‘name‘: ‘阿甘正传‘, ‘name‘: ‘孝庄秘史‘, ‘name‘: ‘神秘的西夏王陵‘] >

# .value_list() queryset对象里套元组
book = models.Book.objects.all().values_list(‘name‘)
# < QuerySet[(‘阿甘正传‘,), (‘孝庄秘史‘,), (‘神秘的西夏王陵‘,)] >

# .distinct() 必须完全一样,才能去重,不适用与用id的查询结果
book = models.Book.objects.all().values(‘name‘).distinct()

1.4 数据的模糊查询

Book.objects.filter(price__in=[45,98,56]) 价格在[]的书
Book.objects.filter(price__gt=100) 	  大于
Book.objects.filter(price__lt=100)	  小于
Book.objects.filter(price__gte=100)	  大于等于
Book.objects.filter(price__lte=100)	  小于等于
Book.objects.filter(price__range=[100,200])   在XX范围内
Book.objects.filter(name__contains="阿")     查询名字有‘%阿%‘的书
Book.objects.filter(name__icontains="python")  查询名字带python的书,忽略大小写
Book.objects.filter(name__startswith="神")    以‘神‘开头的书
Book.objects.filter(date__year=2017)        按年查询

 二、多表操作

案例:以下面这些概念,字段和关系查询

作者模型:一个作者有姓名和性别及其他详细信息。

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

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

书籍模型: 书籍有书名、价格、作者(一本书可能会有多个作者,一个作者也可以写多本书),所以作者和书籍的关系就是多对多的关联关系(ManyToManyField),但是一本书只应该由一个出版社出版,所以出版社和书籍是一对多的关联关系(ForeignKey)。

2.1 创建表操作

  • 创建类,添加字段
技术分享图片models.py
  • 添加出版社信息

Publish.objects.create(name=‘环球出版社‘, address=‘北京‘, email=‘[email protected]‘)
Publish.objects.create(name=‘华夏出版社‘, address=‘北京‘, email=‘[email protected]‘)
  • 添加书籍信息

# pk 为主键,可通过主键查找,也可通过 id 查找
publish = Publish.objects.filter(pk=1).first()
Book.objects.create(name=‘雷神之诸神之怒‘, price=65.9, publish=publish)
Book.objects.create(name=‘雷神之黑暗世界‘, price=75.3, publish=publish)
Book.objects.create(name=‘雷神之诸神黄昏‘, price=45.5, publish=publish)
  • 添加作者详情信息

AuthorDetails.objects.create(phone=‘18800001‘, address=‘昌平‘)
AuthorDetails.objects.create(phone=‘16600002‘, address=‘五环‘)
  • 添加作者信息

au_details = AuthorDetails.objects.filter(id=1).first()
Author.objects.create(name=‘jack‘, sex=1, author_details=au_details)
au_details = AuthorDetails.objects.filter(id=2).first()
Author.objects.create(name=‘peter‘, sex=1, author_details=au_details)

2.2 连表的增删改查

# 获取作者
jack = Author.objects.filter(name=‘jack‘).first()
peter = Author.objects.filter(name=‘peter‘).first()

# 获取书名
book = Book.objects.filter(name=‘雷神之诸神之怒‘).first()
# 一:.add() 添加,可添加一个或多个对象,id
# 为 雷神之诸神之怒 新增作者 jack,peter
book.authors.add(jack, peter)
# 也可以按作者id添加
book.authors.add(1,2)

# 二:.remove() 删除,可以是id,也可以是对象,能传多个值
book.authors.remove(jack) # 按名字删除
book.authors.remove(1, 2) # 按id删除

# 三:.clear() 清空所有,不用传值
book.authors.clear()

# 四:.set() 先清空,再新增,注意点:传的值必须是列表,列表内可以是id,或者对象
book.authors.set([jack,])

2.3 基于对象的连表查询

基于对象的连表查询是子查询,即多次查询

  • 一对一

正向:由关联字段所在的表去查找其他表时---按字段

反向:由其他表去查找关联字段所在的表时---按表名小写

# 正向: 查找作者jack的phone信息时
author = Author.objects.filter(name=‘jack‘).first()
res = author.author_details.phone # author.author_details 作者详情对象
print(res)

# 反向: 查找地址是五环的作者名字
address = AuthorDetails.objects.filter(address=‘五环‘).first()
author = address.author.name # address.author 作者对象
print(author)
  • 一对多

正向: 由关联字段所在的表去查找其他表时---按字段

反向: 由其他表去查找关联字段所在的表时---按表名小写_set.all()

# 正向: 查找 雷神之诸神之怒 的出版社邮箱
book = Book.objects.filter(name=‘雷神之诸神之怒‘).first()
publish_email = book.publish.email
print(publish_email)

# 反向: 查找邮箱是 [email protected] 的出版社出版的 雷神之诸神黄昏 这本书的价格
email = Publish.objects.filter(email=‘[email protected]‘).first()
book = email.book_set.all().filter(name=‘雷神之诸神黄昏‘).values(‘price‘) # email.book_set.all() 拿出的是所有图书
print(book)
  • 多对多

正向: 由关联字段所在的表去查找其他表时---按字段.all()

反向: 由其他表去查找关联字段所在的表时---按表名小写_set.all()

# 正向: 查找 雷神之诸神之怒 的作者信息
book = Book.objects.filter(name=‘雷神之诸神之怒‘).first()
author = book.authors.all()
print(author)

# 反向: 查找 作者jack 所写的书籍
author = Author.objects.filter(name=‘jack‘).first()
books = author.book_set.all()
print(books)

2.4 基于双下划线的连表查询

***正向查询按字段,反向连表查询按表名小写***

  • 一对一

# 查询 作者jack 的phone信息
# 以 Author 表作为基表查询
phone = Author.objects.filter(name=‘jack‘).values(‘author_details__phone‘)

# 以 AuthorDetails 表作为基表查询
phone = AuthorDetails.objects.filter(author__name=‘jack‘).values(‘phone‘)
print(phone)
  •  一对多
# 查询出版社为北京的出版社出版的所有图书的名字、价格
# 以 Publish 为基表查询
res = Publish.objects.filter(name=‘北京出版社‘).values(‘book__name‘,‘book__price‘)
# 以 Book 为基表查询
res = Book.objects.filter(publish__name=‘北京出版社‘).values(‘name‘, ‘price‘)
print(res)
  • 多对多
# 查询 雷神之诸神之怒 的所有作者的名字
# 以 Book 为基表查询
authors = Book.objects.filter(name=‘雷神之诸神之怒‘).values(‘authors__name‘)
# 以 Author 为基表查询
authors = Author.objects.filter(book__name=‘雷神之诸神之怒‘).values(‘name‘)
print(authors)
# 查询图书价格大于30的所有作者的名字
# 以 Book 为基表查询
authors = Book.objects.filter(price__gt=30).values(‘authors__name‘)
# 以 Author 为基表查询
authors = Author.objects.filter(book__price__gt=30).values(‘name‘)
print(authors)
  • 多次连表查询

# 查询 环球出版社 出版过的书籍的名字和作者的名字
# 以 Publish 为基表查询
res = Publish.objects.filter(name=‘环球出版社‘).values(‘book__name‘, ‘book__authors__name‘)
print(res)
# 以 Book 为基表查询
res1 = Book.objects.filter(publish__name=‘环球出版社‘).values(‘name‘, ‘authors__name‘)
print(res1)
# 以 Author 为基表查询
res2 = Author.objects.filter(book__publish__name=‘环球出版社‘).values(‘book__name‘, ‘name‘)
print(res2)

2.5 聚合查询&分组查询

  • 聚合查询 .aggregate()
    • aggregate()QuerySet 的一个终止子句,即它返回一个包含一些键值对的字典
from django.db.models import Avg, Min, Max, Sum, Count

# 计算所有书籍的平均价格,最高价格,最低价格,总和
avg_price = Book.objects.aggregate(Avg(‘price‘))
max_price = Book.objects.aggregate(Max(‘price‘))
min_price = Book.objects.aggregate(Min(‘price‘))
sum_price = Book.objects.aggregate(Sum(‘price‘))
print(avg_price)
print(max_price)
print(min_price)
print(sum_price)

# 查询 环球出版社 出版书籍的数量
count = Publish.objects.filter(name=‘环球出版社‘).aggregate(Count(‘book‘))
print(count)
  • 分组查询 .annotate()
    • annotate()为调用的 QuerySet中每一个对象都生成一个独立的统计值(统计方法用聚合函数)。
# 统计书籍名以‘黄昏‘结尾的书的作者的个数
res = Book.objects.all().filter(name__endswith=‘黄昏‘).annotate(num=Count(‘authors‘)).values(‘name‘,‘num‘)
print(res)

# 总结:以谁分组, 就以谁做基表, filter过滤, annotate取分组, values取值
# 模板
    # values 在前表示group by,在后表示取值
    # filter 在前表示where条件,在后表示having

# 统计书籍名以‘黄昏‘结尾的书的作者的个数(按模板)
res = Book.objects.values(‘name‘).filter(name__endswith=‘黄昏‘).annotate(num=Count(‘authors‘)).values(‘name‘, ‘num‘)
print(res)

# 查询每个作者所出书籍的价格的总和
res = Author.objects.values(‘name‘).annotate(num=Sum(‘book__price‘)).values(‘name‘, ‘num‘)
print(res)

2.6 F查询 & Q查询

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

# F 函数
from django.db.models import F,Q

# 将所有书籍的价格加10元
res = Book.objects.all().update(price=F(‘price‘)+10)
print(res)


# Q 函数
# 表示或(|)、非(~)关系
# 查询作者的名字是jack 或 peter 的 书
res = Book.objects.filter(Q(authors__name=‘jack‘)|Q(authors__name=‘peter‘))
print(res)

2.7 常用字段及参数

  • orm字段
AutoField----->int 自增,必须输入参数primary_key=True
CharField(max_length=[0-255])----->字符类型,必须提供max_length参数
DateTimeField----->日期+时间格式 YY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]
DateField----->日期格式 YY-MM-DD
TimeField----->时间格式 HH:MM[:ss[.uuuuuu]][TZ]
EmailField----->字符串类型
IntegerField----->整数(-2147483648 ~ 2147483647)
PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)----->正整数(0 ~ 2147483647)
NullBooleanField----->可以为空的布尔值
TextField----->文本类型
  • orm字段参数
null - ---->表示某个字段可以为空
unique - ---->值为True时,该字段就必须是唯一的
db_index - ---->值为True时,为该字段设置索引
default - ---->设置默认值


# DateField & DateTimeField
auto_now_add - ---->值为True时,创建数据记录是会将当前时间添加到数据库
auto_now - ---->值为True时,每次更新数据记录都会更新该字段


# ForeignKey
to - ---->设置要关联的表
to_field - ---->设置要关联的字段
related_name - ---->在反向操作时, 使用的字段名,用于代替原反向查询时的‘表名_set‘
# eg:
class Classes(models.Model):
    name = models.CharField(max_length=32)


class Student(models.Model):
    name = models.CharField(max_length=32)
    theclass = models.ForeignKey(to="Classes")

# 反向查询 班级所有的学生时
students = models.Classes.objects.first().student_set.all()

# 但是当设置了 related_name="students" 后
theclass = models.ForeignKey(to="Classes", related_name="students")
# 就可以这样查询
students = models.Classes.objects.first().students.all()

related_query_name - ---->反向查询操作时,使用的连接前缀,用于替换表名
db_constraint - ---->是否在数据库中创建外键约束,默认为True
on_delete - ---->当删除关联表中的数据时,当前表与其关联的行的行为
    # models.CASCADE 删除关联数据,与之关联也删除
    # models.DO_NOTHING 删除关联数据,引发错误IntegrityError
    # models.SET 删除关联数据
        a.与之关联的值设置为指定值,设置:models.SET(值)
        b.与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)


# ManyToManyField
db_table - ---->默认创建第三张表时,数据库中表的名称
through_fields - ---->设置关联的字段
symmetrical - ---->仅用于多对多自关联时,指定内部是否创建反向操作的字段。默认为True

django模型层:单表多表操作f与q查询(代码片段)

DJango模型层单表操作使用有几步:settings.py中配置连接数据库的地址,端口在init.py中使用pymysql在models.py里写类,一个类对应一个表,写属性数据库迁移命令,第一个命令是纪录,第二个命令才是真正的数据库同步导入models到views... 查看详情

数据库之表查询,单表多表,子查询

基本查询语句及方法 from where groupby having distinct orderby limit ....连表 innerjoin leftjoin rightjoin union子查询  书写顺序 selectid,namefromempwhereid>3andid<6;执行顺序 from#确定到底是哪站表 where#根据过来条件筛选数据 s 查看详情

wen应用/路由控制/视图函数/单表多表操作(代码片段)

一、  1.wen应用:BS架构的应用程序,B是浏览器,S:server(实现了wsgi协议)+application    https://www.cnblogs.com/liuqingzheng/articles/9523087.html   2.MVC和MTV(Django)    M:Model和数据库打交道    V:模板    C:... 查看详情

集成代码生成器单表多表树形表一对多springmvcspringmybatisssm后台框架

650)this.width=650;"width="600"height="309"class="zoom"id="aimg_i6sTb"src="https://img.alicdn.com/imgextra/i1/332189337/TB2BndqoXXXXXbpXXXXXXXXXXXX_!!332189337.png?t=1461910434000"border="0"/>获取【下载地址】 查看详情

dmldql与单表多表的增删改查(20190215下午)(代码片段)

MariaDB[db1]>select*fromstudent;+----+------+-----+--------+-------+|id|name|age|gender|phone|+----+------+-----+--------+-------+|1|a|20|m|119||2|b|20|m|120||3|c|20|m|110||4|d|20|m|135||5|e|20|m|121||6|f|20|m|100|+----+------+-----+--------+-------+6rowsinset(0.00sec)修改其中一行内容:M... 查看详情

django-模型层-下(代码片段)

一、单表多表介绍单表多表多对一多对多一对一===============================================一对多:Bookidtitlepricepublish_id1php10012python20013go3002Publishidnameemailaddr1人名出版社@北京2沙河出版社@沙河一旦确定是一对多怎么建立一对多的关系?-... 查看详情

17-2orm单表操作和多表操作(代码片段)

参考:https://www.cnblogs.com/liwenzhou/p/8660826.html一 ORM单表操作1增删改查11.查询21.查所有3models.Publisher.objects.all()42.查某个具体的记录5models.Publisher.objects.get(id=1)-->注意查询条件不成立就报错62.删除一条记录7models.Publish 查看详情

03:数据导入导出表记录基本操作查询及匹配条件多表查询

...二数据导出三管理表记录*3.1插入表记录3.2查询表记录(单表多表嵌套连接)3.3条件匹配3.4更新表记录字段的值3.5删除表记录++++++++++++++++++++++++++++++++一数据导入:把系统文件的内容存储到数据库的表里。把系统已有的用户信息存... 查看详情

MYSQL多表多选

】MYSQL多表多选【英文标题】:MYSQLmultipleselectfrommultipletables【发布时间】:2017-11-1207:54:25【问题描述】:我有X个表,我想要一个查询来获取我想要的所有数据。我想要这个方法的原因是我的数据库中有超过10.000条记录,所以我... 查看详情

转:mvc单表多按钮提交

 有时候会遇到这种情况:在一个表单上需要多个按钮来完成不同的功能,比如一个简单的审批功能。 如果是用webform那不需要讨论,但asp.netmvc中一个表单只能提交到一个Action处理,相对比较麻烦点。方法一:使用客户端脚... 查看详情

orm单表操作查询多表操作查询及增删改查(代码片段)

------------------------------------------只有对前途乐观的人,才能不怕黑暗,才能有力量去创造光明。乐观不是目的,而是人生旅途中的一种态度。 多表操作创建模型实例:我们来假定下面这些概念,字段和关系作者模型:一个作... 查看详情

06-查询操作(dql)

一.综述  查询操作主要从两个方面来说:单表查询和多表查询。单表查询包括:简单查询、过滤查询、结果查询、分页查询、聚集函数;多表查询包括:笛卡尔积、外键约束、内连接查询、外链接查询、自连接查询。二.... 查看详情

sql单表/多表查询去除重复记录

sql单表/多表查询去除重复记录单表distinct多表groupbygroupby必须放在orderby和limit之前,不然会报错************************************************************************************1、查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来... 查看详情

django-orm:单表查询基于对象和双下划线的多表操作集合查询分组查询f查询和q查询(代码片段)

##############################################单表操作##############################################简单查:models.User.objects.filter(id=3)#queryset对象,相当于一个列表,放了一个或多个User对象models.User.objects.filter(id=3).fi 查看详情

linq中的groupby多表多字段,sum求和

vardata=(fromainItemsgroupabynew{a.GroupId,a.Id}intoborderbynewComparerItem(){GroupId=b.Key.GroupId,Id=b.Key.Id}descendingselectnew{GroupId=b.Key.GroupId,Id=b.Key.Id,Count=b.Sum(c=>c.Count),Weight= 查看详情

javalearn#(17)mysql基础知识dml及ddl语句外键及非外键约束外键策略dql语句(单表多表)连接查询子查询索引事务视图存储过程用户权限及角色管理(代码片段)

1.基础知识1.1数据库基础知识数据:计算机可以处理的数据,字母、文字、文本、图形、音频、视频等数据库:Database,以一定格式存放数据,能够实现多个用户共享,与应用程序彼此独立的数据集合数据... 查看详情

javalearn#(17)mysql基础知识dml及ddl语句外键及非外键约束外键策略dql语句(单表多表)连接查询子查询索引事务视图存储过程用户权限及角色管理(代码片段)

1.基础知识1.1数据库基础知识数据:计算机可以处理的数据,字母、文字、文本、图形、音频、视频等数据库:Database,以一定格式存放数据,能够实现多个用户共享,与应用程序彼此独立的数据集合数据... 查看详情

单表的更新update和删除记录delete

...们想改下字段值。那么,我们需要update关键字。update分为单表更新和多表更新。   一、UPDATE语句  UPDATE语句其实有两种方式,分别是单表更新和多表更新,多表更新等到后面我们学完连接以后再去学习,所以今天我... 查看详情