当前位置 : 主页 > 编程语言 > python >

Django(part32)--一对一映射

来源:互联网 收集:自由互联 发布时间:2022-06-15
学习笔记,仅供参考 文章目录 ​​数据表关联关系映射​​ ​​一对一映射​​ ​​语法​​ ​​创建一对一的数据记录​​ ​​查询​​ ​​作用​​ ​​举个例子​​ 数据表

学习笔记,仅供参考



文章目录

  • ​​数据表关联关系映射​​
  • ​​一对一映射​​
  • ​​语法​​
  • ​​创建一对一的数据记录​​
  • ​​查询​​
  • ​​作用​​
  • ​​举个例子​​


数据表关联关系映射



在关系型数据库中,通常不会把所有数据都放在同一张表中,这样做会额外占用内存空间,这时,我们会使用表关联对各个数据表进行联结。



  • 常用的表关联方式有三种:
  • 一对一映射(如: 一个身份证对应一个人)
  • 一对多映射(如: 一个班级可以有多个学生)
  • 多对多映射(如: 一个学生可以报多个课程,一个课程可以有多个学生学习)


一对一映射



一对一是表示事物之间存在的一对一的对应关系。



语法



#主类
class A(model.Model):
...

#从属类
class B(model.Model):
属性 = models.OneToOneField(A)



  • 例子(作家和作家伴侣类)
#models.py
from django.db import models

class Author(models.Model):
'''作家模型类'''
name = models.CharField('作家', max_length=50)

class Partner(models.Model):
'''作家伴侣模型类'''
name = models.CharField("伴侣", max_length=50)
author = models.OneToOneField(Author)
# 增加与作家的一对一属性




创建一对一的数据记录



from bookstore import models
author1 = models.Author.objects.create(name='黄永祥')
partner1 = models.Partner.objects.create(name='黄夫人', author=author1)
#关联黄永祥作家
author2 = models.Author.objects.create(name='王军')
# 一对一关系中,主类对象可以没有对应的从属类对象



查询



在Partner对象中,通过author属性找到对应的author对象;

在Author对象中,通过 partner属性找到对应的partner对象.



  • 正向查询

直接通过关联属性查询即可:

# 通过partner找author
from bookstore import models
partner = models.Partner.objects.get(name='黄夫人')
print(partner.name, '的伴侣是', partner.author.name)
  • 反向查询

反向查询为通过反向引用属性查询,反向引用属性为​​实例对象.引用类名​​​(引用类名要小写),如作家的反向引用为​​作家对象.partner​​,需要注意的是,当反向引用不存在时,则会触发异常

#author可以通过author.partner查找partner,如果没有对应的partner则触发异常
author1 = models.Author.objects.get(name='黄永祥')
print(author1.name, '的伴侣是', author1.partner.name)
author2 = models.Author.objects.get(name='王军')
try:
print(author2.name, '的伴侣是', author2.partner.name)
except:
print(author2.name, '还没有伴侣')



作用



一对一映射主要是解决数据的存储问题,把经常加载的一个数据放在主表中,不常用数据放在另一个副表中,这样,在访问主表数据时就不需要加载副表中的数据,以提高访问速度和节省内存空间,如经常把书的内容和书名建成两张表,因为在网站上经常访问书名等信息,但不需要得到书的内容。



举个例子



首先,我们在models.py中创建一个Partner模型类,并作为Author类的从属类,形成一对一关系:

class Partner(models.Model):
'''作家伴侣模型类'''
name = models.CharField("姓名", max_length=50)
age = models.IntegerField("年龄", null = False,
default = 1)
author = models.OneToOneField(Author, on_delete = models.CASCADE)

记得做一下迁移:

F:\MyStudio\PythonStudio\goatbishop.project01\Django\mywebsite_db>python manage.py makemigrations
Migrations for 'bookstore':
bookstore\migrations\0006_auto_20200621_2334.py
- Alter field age on author
- Create model Partner

F:\MyStudio\PythonStudio\goatbishop.project01\Django\mywebsite_db>python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, bookstore, contenttypes, sessions
Running migrations:
Applying bookstore.0006_auto_20200621_2334... OK

需要注意的是,如果我们在OneToOneField中没有加参数​​on_delete=models.CASCADE​​,则在使用python manage.py makeigrations 进行迁移时就会报错。如果我们加入这个参数,则在删除主表的数据时,从表中的数据也会随之删除。

现在,打开Django shell创建记录:

from bookstore import models
author1 = models.Author.objects.create(name='黄永祥', age = 40, email="yxhuang@163.com")
partner1 = models.Partner.objects.create(name='黄夫人', age = 39, author=author1)
#关联黄永祥作家
author2 = models.Author.objects.create(name='王军', age = 36, email="wangjun@163.com")

再查看一下mywebdb数据库中 bookstore_partner表和bookstore_author表:

mysql> select * from bookstore_author;
+----+--------+-----+----------------------+
| id | name | age | email |
+----+--------+-----+----------------------+
| 1 | 山羊 | 20 | goatbishop@gamil.com |
| 2 | 小黄 | 11 | 1033794241@qq.com |
| 5 | 小黑 | 13 | xiaohei@gmail.com |
| 6 | 小白 | 19 | xiaobai@gmail.com |
| 7 | 山羊哥 | 28 | biggoat@gmail.com |
| 8 | 黄永祥 | 40 | yxhuang@163.com |
| 9 | 王军 | 36 | wangjun@163.com |
+----+--------+-----+----------------------+
7 rows in set (0.00 sec)

mysql> select * from bookstore_partner;
+----+--------+-----+-----------+
| id | name | age | author_id |
+----+--------+-----+-----------+
| 1 | 黄夫人 | 39 | 8 |
+----+--------+-----+-----------+
1 row in set (0.00 sec)

我们看到bookstore_partner表中黄夫人的author_id字段值为8,它对应着bookstore_author表中的id值8



我们再做一些查询工作:

#正向
partner = models.Partner.objects.get(name='黄夫人')
print(partner.name, '的伴侣是', partner.author.name)
#反向
author1 = models.Author.objects.get(name='黄永祥')
print(author1.name, '的伴侣是', author1.partner.name)
author2 = models.Author.objects.get(name='王军')
try:
print(author2.name, '的伴侣是', author2.partner.name)
except:
print(author2.name, '还没有伴侣')

输出:

黄夫人 的伴侣是 黄永祥
黄永祥 的伴侣是 黄夫人
王军 还没有伴侣

上一篇:Django(part31)--admin后台数据库管理
下一篇:没有了
网友评论