多表操做python
三种关系:一对一,一对多,多对多mysql
1、数据准备,建立表模型git
配置settings,链接到数据库
# settings更改配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'orm03',
'HOST':'127.0.0.1',
'PORT':3306,
'USER':'root',
'PASSWORD':'123'
}
}sql
# 项目中的init写入: import pymysql pymysql.install_as_MySQLdb()
在应用中的models.py建立模型
from django.db import models数据库
# 比较经常使用的信息放到这个表里面 class Author(models.Model): nid = models.AutoField(primary_key=True) name=models.CharField( max_length=32) age=models.IntegerField() authorDetail=models.OneToOneField( to="AuthorDetail", to_field="nid", on_delete=models.CASCADE # on_delete=models.SET_NULL()设置不级连删除,对方删除后,本身设置为空 ) # 与AuthorDetail创建一对一的关系(OneToOneField),一对一的这个关系字段写在两个表的任意一个表里面均可以 # 就是foreignkey+unique,只不过不须要咱们本身来写参数了,而且orm会自动帮你给这个字段名字拼上一个_id,数据库中字段名称为authorDetail_id # 不经常使用的放到这个表里面 class AuthorDetail(models.Model): nid = models.AutoField(primary_key=True) birthday=models.DateField() # telephone=models.BigIntegerField() 不方便之后查询,须要再转str查,不如直接用str类型 telephone=models.CharField(max_length=30) addr=models.CharField(max_length=64) # 与Author创建一对一的关系(OneToOneField这个关系字段写在两个表的任意一个表里面均可以) class Publish(models.Model): nid = models.AutoField(primary_key=True) name=models.CharField( max_length=32) city=models.CharField( max_length=32) email=models.EmailField() # 至关于CharField,后期可多一层校验规则,判断是不是xx.@...这样的邮箱地址 # 多对多的表关系,在mysql的时候创建这种关系,须要手动建立一个第三张表,而后写上两个字段,每一个字段外键关联到另外两张多对多关系的表;orm的manytomany自动帮咱们建立第三张表,两种方式创建关系均可以,之后的学习咱们暂时用orm自动建立的第三张表,由于手动建立的第三张表咱们进行orm操做的时候,不少关于多对多关系的表之间的orm语句方法没法使用 #若是你想删除某张表,你只须要将这个表注销掉,而后执行那两个数据库同步指令就能够了,自动就删除了。 # 与Publish创建一对多的关系 # 与Author创建多对多的关系 class Book(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField( max_length=32) publishDate=models.DateField() price=models.DecimalField(max_digits=5,decimal_places=2) publish=models.ForeignKey( to="Publish", to_field="nid", on_delete=models.CASCADE ) # 与Publish创建一对多的关系,外键字段创建在多的一方,字段publish若是是外键字段,那么它自动是int类型 #foreignkey里面能够加不少的参数,to指向表,to_field指向你关联的字段,不写这个,默认会自动关联主键字段,on_delete级联删除 #字段名称不须要写成publish_id,orm在翻译foreignkey的时候会自动给你这个字段拼上一个_id,这个字段名称在数据库里面就自动变成了publish_id # 与Author表创建多对多的关系,ManyToManyField能够建在两个模型中的任意一个,自动建立第三张表,而且注意一点,你查看book表的时候,你看不到这个字段,由于这个字段就是建立第三张表的意思,不是建立字段的意思,因此只能说这个book类里面有authors这个字段属性 authors=models.ManyToManyField(to='Author') # 注意不论是一对多仍是多对多,写to这个参数的时候,最后后面的值是个字符串,否则你就须要将你要关联的那个表放到这个表的上面
总结:
建立表:django
一对一:# OneToOneField xx = models.OneToOneField( to='表名', to_field='字段名', on_delete=models.CASCADE ) # to_field能够不写,默认是关联到另外一张表的主键 # on_delete在1.x版本的django中不用写,默认是级联删除的,2.x版本的django要写 # on_delete=models.SET_NULL()设置不级连删除,对方删除后,本身设置为空 一对多:# ForeignKey xx = models.ForeignKey( to='表名', to_field='字段名', on_delete=models.CASCADE ) 多对多:# ManyToManyField xx = models.ManyToManyField(to='另一个表名') #这是自动建立第三表 # 还能够手动建立第三张表,(用在还有其余一些本身的字段的时候,暂时忽略) # class BookToAuthor(models.Model): # book_id = models.ForeignKey(to='Book') # author_id = models.ForeignKey(to='Author') # xx = models.CharField(max_length=12) 注意:不论是一对多仍是多对多,写to这个参数的时候,最后后面的值是个字符串,否则你就须要将你要关联的那个表放到这个表的上面
执行数据库同步指令:
python manage.py makemigrations
python manage.py migrate
结果以下:app
2、关系表添加记录
学习
拓展一种添加数据的方式,是django内部提供的一个后台管理系统翻译
建立一个超级用户:
python manage.py createsuperuser3d
Username (leave blank to use 'administrator'): yangzm Email address: Password: 94211314ming.
访问127.0.0.1:8000/admin/,使用刚注册好的用户名、密码,登陆后台管理系统
在应用app01下的admin.py注册咱们要用的表
from django.contrib import admin
from app01 import models # 导入models
# Register your models here. admin.site.register(models.Author) # admin.site.register方法注册 admin.site.register(models.Publish) admin.site.register(models.Book) admin.site.register(models.AuthorDetail)
从新运行项目,就会发现表已经在后台的管理系统当中了
点击里面的添加按钮,根据要求,就能够添加数据了
增
一对一表的增长
一对一关联的表是:Author表的authorDetail字段关联的 AuthorDetail表的nid字段
def query(request):
new_author_detail = models.AuthorDetail.objects.create( birthday='1996-02-14', telephone='188753698755', addr='天界大陆' ) # 方式1: models.Author.objects.create( name='liangdao', age='26', authorDetail=new_author_detail # 直接等于对象 ) new_author_obj = models.AuthorDetail.objects.create( birthday='1886-02-14', telephone='18615724935', addr='幽暗密林' ) # 方式2:(经常使用) models.Author.objects.create( name='baobao', age='55', authorDetail_id=new_author_obj.nid # 把对象的id属性关联起来 )
一对多的增长
一对多关联的表是:Book表的publish字段关联的 Publish表的nid字段
# 方式1:
models.Book.objects.create(
title='回村的诱惑',
publishDate='2018-12-12',
price=88.88,
publish=models.Publish.objects.get(nid=1)
)
# 方式2:(经常使用)
models.Book.objects.create(
title='回村的诱惑2',
publishDate='2000-11-11',
price=45,
publish_id=models.Publish.objects.get(nid=1).nid
)
多对多的增长
多对多关联的表是:Book表的authors字段关联的 Author表的nid字段
# 方式1:经常使用
book_obj = models.Book.objects.get(nid=1)
book_obj.authors.add([1,2])
# 方式2:
author1 = models.Author.objects.get(nid=1)
author2 = models.Author.objects.get(nid=3)
book_obj = models.Book.objects.get(nid=2)
book_obj.authors.add([author1, author2])
一对一和一对多的删除和单表删除是同样的
一对多的删
# Book表一对多关联Publish表
models.Publish.objects.get(nid=2).delete()
# Publish表删除数据,影响到Book表
models.Book.objects.get(nid=7).delete()
# Book表删除数据,不会影响到Publish表
多对多关系的删除
实际上就是去删除多对多自动生成的表中的关系的记录
# Book表多对多的关联Author表
book_obj = models.Book.objects.get(nid=3)
book_obj.authors.remove(3)
# 先找到book里id是3的书,而后经过authors属性删除做者id是3的数据
book_obj = models.Book.objects.get(nid=3) book_obj.authors.remove(*[2,3]) # 先找到book里id是3的书,而后经过authors属性删除做者id是2和3的数据 book_obj = models.Book.objects.get(nid=3) book_obj.authors.clear() # 先找到book里id是3的书,而后经过authors属性找到关系表,删除全部id是3的书数据 book_obj = models.Book.objects.get(nid=3) book_obj.authors.clear() book_obj.authors.add(*[1,]) # 先删除全部id是3的书数据,而后给id是3的书加入一个id是1的做者 book_obj = models.Book.objects.get(nid=3) book_obj.authors.set('1') # 一样完成上述需求,先清空再添加(set必须给个参数,不然报错) book_obj = models.Book.objects.get(nid=3) book_obj.authors.set(['5','6']) # 删除而后更新,添加多个注意:
一对一
models.Author.objects.filter(nid=6).update(
name='baoge',
age='16',
authorDetail=models.AuthorDetail.objects.get(nid=5)
# authorDetail_id = 4 两种方式
)
一对多
models.Book.objects.filter(pk=6).update(
title='回娘家的诱惑',
price=188,
publish=models.Publish.objects.get(pk=2)
models.Publish.objects.filter(pk=2).update( id=4, # 没有级联更新,报错!! ) # 注:默认级联删除,级联更新没有默认
多对多
# 就是set
book_obj = models.Book.objects.get(nid=3) book_obj.authors.set('1') # 一样完成上述需求,先清空再添加(set必须给个参数,不然报错) book_obj = models.Book.objects.get(nid=3) book_obj.authors.set(['5','6']) # 删除而后更新,添加多个