目录
- from django.db import models
-
- # Create your models here.
-
- # 表app01_publish
- class Publish(models.Model):
- name = models.CharField(max_length=20)
- addr = models.CharField(max_length=20)
-
- # 表app01_authordetail
- class AuthorDetail(models.Model):
- tel = models.CharField(max_length=20)
-
- # 表app01_author
- class Author(models.Model):
- name = models.CharField(max_length=20)
- age = models.IntegerField()
-
- # 表app01_author一对一表app01_authordetail
- detail = models.OneToOneField(to='AuthorDetail',to_field='id',unique=True,on_delete=models.CASCADE)
-
-
- # 表app01_book
- class Book(models.Model):
- title = models.CharField(max_length=20)
- price = models.DecimalField(max_digits=8, decimal_places=2)
- pub_date = models.DateField(auto_now_add=True)
-
- # 表app01_book多对一表app01_publish,参数to指定模型名,参数to_field指定要关联的那个字段
- publish = models.ForeignKey(to='Publish',to_field='id',on_delete=models.CASCADE)
-
- # 我们自己写sql时,针对书籍表与作者表的多对关系,需要自己创建新表,而基于django的orm,下面这一行代码可以帮我们自动创建那张关系表
- authors=models.ManyToManyField(to='Author')
- # 变量名为authors,则新表名为app01_book_authors,若变量名为xxx,则新表名为app01_book_xxx
按照上图所示.由于foreignkey的关系, 我们需要实现往 app01_publish 与app01_authordetail里插入记录
- # 1、需求:通过模型Publish往表app01_publish里插入三家出版社
- Publish.objects.create(name='北京出版社')
- Publish.objects.create(name='长春出版社')
- Publish.objects.create(name='大连出版社')
-
- # 2、需求:通过模型AuthorDetail往表app01_authordetail里插入三条作者详情
- AuthorDetail.objects.create(tel='12345678900')
- AuthorDetail.objects.create(tel='98765432100')
插入时会涉及到多张表, 我们同样分三种情况来介绍
一对一, 一对多关系使用create()方法 , 多对多关系使用add()方法
需求: 书籍(葵花宝典, 菊花宝典, 桃花宝典)都是在北京出版社出版的
- # 线通过魔心Publish从出版社表app01_publish查出北京出版社
-
- publish_obj = Publish.objects.filter(name='北京出版社').first()
方式一: 使用publish_id参数指定关联
在有出版社id的情况下, 可以直接指定
- models.Book.objects.create(title='葵花宝典',price=200,publish_id=1)
- models.Book.objects.create(title='菊花宝典', price=3000, publish_id=1)
- models.Book.objects.create(title='桃花宝典', price=4000, publish_id=1)
方式二: 使用publish参数指定关联
对于外键字段也可以直接传入想要关联的外键对象, 不过字段名就不是表中的字段名, 而是想要关联的表名
models.Book.objects.create(title='三国志',price='123.99',publish=publish_obj)
需求: 插入三个作者,并于作者详情表一一对应
注意: 一对一字典是唯一对应的 不能重复
- # 方式一:需要事先过滤出作者详情的对象,然后通过模型Author的字段author来指定要关联的作者详情对象
- author_obj1 = Author.objects.filter(pk=1)
- Author.objects.create(name='egon',age=18,author = author_obj1)
- ...# 剩下的省略
-
- # 方式二:确定作者详情对象的id,然后通过模型Author通过字段author_id来指定关联关系,
- Author.objects.create(name='egon',age=18,author_detail_id=1)
- Author.objects.create(name='kevin',age=38,author_detail_id=2)
- Author.objects.create(name='rose',age=28,author_detail_id=3)
add()方法
需要注意: 在那个表中创建的ManyToMAnyField对应的虚拟字段, 那么就使用那个表的add()方法
方式一: 根据对象添加
在原生sql中, 多对多关系涉及到操作第三章表关系, 但是在ORM中我们只需要操作模型类Book下的字段author即可
- # 1、先获取书籍对象
- book_obj1=Book.objects.get(title='葵花宝典')
-
- # 2、然后获取作者对象
- lili=Author.objects.get(name='lili')
- frank=Author.objects.get(name='frank')
-
- # 3、最后依次创建上述关系:
- book_obj1.authors.add(lili,frank)
方式二: 直接传入主键值
- book_obj1=Book.objects.get(title='菊花宝典')
- book_obj1.authors.add(1)
-
- book_obj1=Book.objects.get(title='桃花宝典')
- book_obj1.authors.add(1,4)
update()方法
同样是两种方式, 传入修改的字段, 或者传入一个对象
- # 方式一:
- Book.objects.filter(title='三国志').update(publish_id=2)
-
- # 方式二:
- publish_obj = Publish.objects.filter(pk=2).first
- .objects.filter(title='三国志').update(publish=publish_obj)
set()方法
该方法, 括号内需要传入的是可迭代对象
需要注意, 在那个表中创建的ManyToManyField对应的虚拟字段, 那么就使用那个表的add()方法
方式一: 根据对象添加
- # 1、先获取书籍对象
- book_obj1=Book.objects.get(title='葵花宝典')
-
- # 2、然后获取作者对象
- lili=Author.objects.get(name='lili')
- frank=Author.objects.get(name='frank')
-
- # 3、最后修改上述关系:
- book_obj1.authors.set([lili,frank])
方式二: 直接传入主键值
- book_obj1=Book.objects.get(title='菊花宝典')
- book_obj1.authors.set([2,1])
django1.x 外键字段默认就是级联删除, 2.x及以上版本,需要自己指定on_delete字段
- Publish.objects.filter(pk=3).delete()
- # 出版社表删除了主键为 3 的,那么书籍表中出版社ID 为 3 的书籍也会被删除
该方法可以删除一个或者多个
方式一: 根据对象删除
- # 1、先获取书籍对象
- book_obj1=Book.objects.get(title='葵花宝典')
-
- # 2、然后获取作者对象
- lili=Author.objects.get(name='lili')
- frank=Author.objects.get(name='frank')
-
- # 3、最后修改上述关系:
- book_obj1.authors.remove([lili,frank])
方式二: 直接传入主键值
- book_obj1=Book.objects.get(title='菊花宝典')
- book_obj1.authors.remove([2,1])
该方法用于清空
- book_obj1=Book.objects.get(title='菊花宝典')
- book_obj1.authors.clear()
一对一关系., 一对多关系的操作都是一样的, >>> 找到外键字段所在的表, 然后根据该表进行操作
多对多关系的表操作. 需要先找到外键字段所在的表, 然后再确定另一张表中需要操作的字段, 最后再根据外键字段所在的表进行操作, 并且操作所使用的方法是不同的