一.创建表
作者表:
class Author(models.Model):
nid = models.AutoField(primary_key=True)
name=models.CharField( max_length=32)
age=models.IntegerField()
# 与AuthorDetail建立一对一的关系,一对一的这个关系字段写在两个表的任意一个表里面都可以
authorDetail=models.OneToOneField(to="AuthorDetail",to_field="nid",on_delete=models.CASCADE)
# orm会自动帮你给这个字段名字拼上一个_id,数据库中字段名称为authorDetail_id
参数解释:
# 注意:
# 1.x版本默认是级联的可以不加on_delete=models.CASCADE 但是2.x版本一定要加
# models.SET_NULL:不做级联 如果关联的表AuthorDetail将数据删除了 那么Author将为null
# 如果关联的表中有定义id字段可以使用to_field="id字段名" 如果关联的表中没有定义id字段 mysql默认会加上id这个字段 这里的to_field就不用定义,to指向表,to_field指向你关联的字段
# 一对一的关系用OneToOneField来建立,这个关系字段写在两个表的任意一个表里面都可以
#作者信息表
class AuthorDetail(models.Model):
nid = models.AutoField(primary_key=True)
birthday=models.DateField()
telephone=models.CharField()
addr=models.CharField( max_length=64)
#出版社
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 但是使用EmailField方便后续校验是不是Email格式
#书籍表
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建立一对多的关系,外键字段建立在多的一方,字段publish如果是外键字段,那么它自动是int类型
publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)
#foreignkey里面可以加很多的参数,都是需要咱们学习的,慢慢来,to指向表,to_field指向你关联的字段,
# 不写这个,默认会自动关联主键字段,on_delete级联删除字段名称不需要写成publish_id,orm在翻译foreignkey的时候会自动给你这个字段拼上一个_id,这个字段名称在数据库里面就自动变成了publish_id
# 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,
# 自动创建第三张表,并且注意一点,你查看book表的时候,你看不到这个字段,
# 因为这个字段就是创建第三张表的意思,不是创建字段的意思,
# 所以只能说这个book类里面有authors这个字段属性
authors=models.ManyToManyField(to='Author') #注意不管是一对多还是多对多,写to这个参数的时候,最后后面的值是个字符串,不然你就需要将你要关联的那个表放到这个表的上面
上述表关系:
# 作者表和作者详细信息表是一对一的关系
# 作者表和书籍表是多对多的关系
# 出版社和书籍表是一对多的关系 但是实际业务中不一定是
# 在orm中可以通过属性来创建第三张表 authors=models.ManyToManyField(to='Author',)
# 一对一:models.OneToOneField(to="AuthorDetail",to_field='id',on_delete=models.CASCADE)
# 一对多:models.ForeignKey(to="Publish",to_field="id",on_delete=models.CASCADE)
# 多对多:models.ManyToManyField(to='Author',) 自动创建第三张表
这里django中是使用ManyToManyField来创建第三张表,如果我们单独创建的话需要这样:
这张表就是作者和书籍的多对多的关系 这种方式没法使用orm提供多对多表中的一些操作方法,所以不建议使用
我们直接使用authors=models.ManyToManyField(to='Author',)就会形成第三张表,将来我们直接使用authors来操作第三张表
class BookToAuthor(models.Model):
book_id = models.ForeignKey(to='Book')
author_id = models.ForeignKey(to='Author')
创建出来的第三张表:
表关系梳理流程:
二.使用admin给关系表添加记录
admin后台创建数据:
之前我们学单表的时候是直接写代码添加或者在Python console里面也可以添加,现在我们学习在admin后台给表添加数据
from django.conf.urls import url,include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls), #访问这个地址就可以到我们的admin后台
]
这里需要用户名密码,我们要先创建(命令):createsuperuser
要想在我们admin后台操作这些表,需要在我们APP应用下admin.py文件下注册表信息:
from django.contrib import admin
from app02 import models
# Register your models here.
admin.site.register(models.Book)
admin.site.register(models.Author)
admin.site.register(models.AuthorDetail)
admin.site.register(models.Publish)
注意:注册完需要重启一下我们的项目
三.orm语句增删改查
orm语句添加数据:
**1.1一对一增加:**
new_author_detail = models.AuthorDetail.objects.create(
birthday='2012-12-15',
telephone='138316464',
addr='黑龙江哈尔滨'
)
方式一:
models.Author.objects.create(
name='麻子',
age=25,
authorDetail=new_author_detail #直接写model对象
)
方式二:
obj= models.AuthorDetail.objects.filter(addr='山西临汾').first()
models.Author.objects.create(
name='麻子',
age=25,
authorDetail_id=obj.nid,
)
**1.2一对多增加:**
方式一:
models.Book.objects.create(
title='张三的床头故事',
publishDate='2019-07-22',
price=23,
publishs=models.Publish.objects.get(nid=4)
)
方式二:
obj = models.Publish.objects.get(nid=3)
models.Book.objects.create(
title='张三的床头故事2',
publishDate='2019-07-23',
price=15,
publishs_id=obj.nid 常用
)
**1.3多对多增加:**
方式一:
book_obj = models.Book.objects.get(nid=1)
book_obj.authors.add(*[1,2]) #常用
方式二:
author1 = models.Author.objects.get(nid=2)
author2 = models.Author.objects.get(nid=3)
book_obj = models.Book.objects.get(nid=5)
book_obj.authors.add(*[author1, author2])
orm语句删除数据:
# 一对一和一对多的和单表删除是一样的
models.AuthorDetail.objects.get(nid=1).delete() #级联删除
# 需要理解的地方:author表是关联到authordetail表中,
# 如果authordetail中删除一条记录,那么author表中的记录也会被删除
# authordetail表属于被关联者
# 总结:表1外键关联到表二,表1删除,不影响表2,表2删除会影响表1
models.Author.objects.get(nid=3).delete()
#这里我删除author表中的数据是不影响到authordetail表的数据,因为是author表关联authordetail表
# 一对多删除:
models.Publish.objects.get(nid=1).delete()
models.Book.objects.get(nid=3).delete()
#多对多删除
book_obj = models.Book.objects.get(nid=2)
book_obj.authors.remove(5) #删除单个
book_obj.authors.remove(*[5,3]) #删除多个
book_obj.authors.clear() #全部删除
book_obj.authors.set('3') #清空完了再设置
book_obj.authors.set(['2','3']) #清空完了再设置多个作者
orm语句更新数据:
```python
# 更新数据:
# 多对多的更新
book_obj = models.Book.objects.get(nid=2)
book_obj.authors.set(['2', '3']) # 删除然后更新
# 一对一的更新:
obj = models.AuthorDetail.objects.get(nid=2)
models.Author.objects.filter(nid=2).update(
name='张胜男',
age=15,
authorDetail=models.AuthorDetail.objects.get(nid=10) #第一种
authorDetail_id=obj.nid #第二种
)
# 一对多的更新:
obj = models.Publish.objects.get(pk=4) #id可以写成pk pk=Primary key
models.Book.objects.filter(pk=6).update(
title='b哥的往事2',
publishs=models.Publish.objects.get(nid=3) #第一种
publishs_id=obj.nid #第二种
)
# 级联更新:一对一和一对多是一样的
models.Publish.objects.filter(pk=4).update(
nid=2, #没有级联更新 报错
#有级联删除但是没有级联更新
#报错信息:(1451, 'Cannot delete or update a parent row: a foreign key constraint fails (`orm`.`app02_book`, CONSTRAINT `app02_book_publishs_id_2f1300e0_fk_app02_publish_nid` FOREIGN KEY (`publishs_id`) REFERENCES `app02_publish` (`nid`))')
)