Django版本:
>>> django.VERSION (4, 1, 0, 'final', 0)
PS:基于前几章的进度进行修改
一、Django ORM 多表实例
- 表与表之间的关系可以分为以下三种:
一对一
:一个人对应一个的身份证号,数据字段设置为unique一对多
:一个家庭有多个人,一般通过外键来实现多对多
:一个学生有多门课程,一个课程有很多学生,一般通过第三个表来实现关联
下面是菜鸟的示例图
创建模型
- 修改
app1/app1_model/models.py
# -*- coding: utf-8 -*- from django.db import models class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=5,decimal_places=2) pub_date = models.DateField() publish = models.ForeignKey("Publish",on_delete=models.CASCADE) #多对一 authors = models.ManyToManyField("Author") #多对多 class Publish(models.Model): name = models.CharField(max_length=32) city = models.CharField(max_length=64) email = models.EmailField() class Author(models.Model): name = models.CharField(max_length=32) age = models.SmallIntegerField() au_detail = models.OneToOneField("AuthorDetail",on_delete=models.CASCADE) #一对一 class AuthorDetail(models.Model): gender_choices = ( (0,"女"), (1,"男"), (2,"保密"), ) gender = models.SmallIntegerField(choices=gender_choices) tel = models.CharField(max_length=32) addr = models.CharField(max_length=64) birthday = models.DateField()
- 说明:
EmailField数据类型是邮箱格式,底层继承CharField进行了封装,相当于Mysql中的varchar
一般不需要级联更新
如果有模型类存在外键,在创建数据时,需要先创建外键关联的模型类数据,否则在创建包含外键的模型类数据时,外键的关联模型类数据会找不到
设置一对一OneToOneField = ForeignKey("关联类名",unique=True)
外键在一对多中设置,即models.ForeignKey("关联类名",on_delete=models.CASCADE),后面是设置外键删除时的操作:
CASCADE:默认选项,表示级联删除
PROTECT:保护模式,使用该选项,在删除时,会抛出ProtectedError的错误
SET_NULL:置空模式,删除时,外键字段被设置为空,前提是blank=True、null=True,定义该字段时,需要外键允许为空
SET_DEFAULT:删除时,外键字段设置为默认值,使用该选项时,需要注意外键的上一个默认值
SET( ):括号里可以是函数,设置自定义的值
DO_NOTHING:什么也不做
在终端创建数据表
(test) PS F:\django\app1> python .\manage.py makemigrations app1_model Migrations for 'app1_model': app1_model\migrations\0002_authordetail_publish_alter_book_id_author_and_more.py - Create model AuthorDetail - Create model Publish - Alter field id on book - Create model Author - Add field authors to book - Alter field publish on book (test) PS F:\django\app1> python .\manage.py migrate app1_model Operations to perform: Apply all migrations: app1_model Running migrations: Applying app1_model.0002_authordetail_publish_alter_book_id_author_and_more... OK
- 查看mysql数据库,可以看到有一个
app1_model_book_authors
这个就是多对多的第三张表
插入数据
insert into app1_model_publish(name,city,email) values ("华山出版社","华山","hs@163.com"),("明教出版社","黑木崖","mj@163.com"); # 先插入 authordetail 表中多数据 insert into app1_model_authordetail(gender,tel,addr,birthday) values (1,13432335433,"华山","1994-5-23"),(1,13943454554,"黑木崖","1961-8-13"),(0,13878934322,"黑木崖","1996-5-20"); # 再将数据插入 author,这样 author 才能找到 authordetail insert into app1_model_author(name,age,au_detail_id) values ("令狐冲",25,1),("任我行",58,2),("任盈盈",23,3);
- 执行
二、ORM 插入数据
一对多—外键 ForeignKey
方式一:传输对象的形式,返回值的数据类型是对象,即书籍对象
- 具体步骤:
- 获取出版社对象
- 给书籍的出版社属性
pulish
传入出版社对象
- 修改app1/app1/views.py文件 # -*- coding: utf-8 -*- from django.shortcuts import render,HttpResponse from app1_model import models def add_book(request): #books = models.Book.objects.create(title="Python",price=500,publish="Python出版社",pub_date="1970-12-10") pub_obj = models.Publish.objects.filter(pk=1).first() book = models.Book.objects.create(title="Python教程",price=200,pub_date="2011-11-11",publish=pub_obj) print(book,type(book)) return HttpResponse(book)
- 访问
127.0.0.1:8000/add_book
方式二:传入对象id的形式
由于传过来的数据一般都是id,所以传入对象id是比较常用的
在一对多中,设置外键属性的类中,即指多的表,Mysql中显示的字段名称是外键属性名_id,返回值的数据类型是对象,即书籍对象
步骤:
获取出版社对象的id
给书籍的关联出版社字段pulish_id传入出``版社对象的id`
- 修改app1/app1/views.py文件 # -*- coding: utf-8 -*- from django.shortcuts import render,HttpResponse from app1_model import models def add_book(request): #books = models.Book.objects.create(title="Python",price=500,publish="Python出版社",pub_date="1970-12-10") pub_obj = models.Publish.objects.filter(pk=1).first() pk = pub_obj.pk book = models.Book.objects.create(title="Django教程",price=100,pub_date="2012-12-12",publish_id=pk) print(book,type(book)) return HttpResponse(book)
- 访问测试
多对多(Many ToManyField):在第三张表添加数据
方式一:传入对象形式,没有返回值
- 步骤:
- 获取作者对象
- 获取书籍对象
- 给书籍对象的
authors
属性用add
的方法纯如作者对象
- 修改app1/app1/views.py文件 # -*- coding: utf-8 -*- from django.shortcuts import render,HttpResponse from app1_model import models def add_book(request): #books = models.Book.objects.create(title="Python",price=500,publish="Python出版社",pub_date="1970-12-10") chong = models.Author.objects.filter(name="令狐冲").first() book = models.Book.objects.filter(title="Python教程").first() book.authors.add(chong) return HttpResponse(book)
- 访问
127.0.0.1:8000/add_book
进行测试
- 查看数据库信息
方式二:传入对象id形式,没有返回值
- 步骤:
- 获取作者对象的id
- 获取书籍对象
- 给书籍对象的
authors
属性使用add
的方法传入作者的id
# -*- coding: utf-8 -*- from django.shortcuts import render,HttpResponse from app1_model import models def add_book(request): #books = models.Book.objects.create(title="Python",price=500,publish="Python出版社",pub_date="1970-12-10") #chong = models.Author.objects.filter(name="令狐冲").first() xing = models.Author.objects.filter(name="任我行").filter() for i in xing: print(i.pk) book = models.Book.objects.filter(title="Django教程").first() book.authors.add(i.pk) return HttpResponse(xing)
访问127.0.0.1:8000/add_book进行测试
- 查看数据库信息