前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Django中的关系映射

Django中的关系映射

作者头像
Yuou
发布2022-09-26 15:15:44
1.7K0
发布2022-09-26 15:15:44
举报
文章被收录于专栏:乱七八糟技术日常

什么是关系映射?

  • 在关系型数据库中,通常不会把所有数据都放在同一张表中,不易于扩展。

常见的关系映射

  • 一对一映射:例如一个身份证对应一个人
  • 一对多映射:例如一个班级可以有多个学生
  • 一对多映射:例如一个学生可以报考多个课程,一个课程可由多个学生学习.

一对一映射(创建)

  • 一对一是表示现实事物间存在的一对一的对应关系。
  • 语法:OneToOneField(类名,on_delete=xxx)
代码语言:javascript
复制
class Asset (models.Model):

    create_date = models.DateTimeField(verbose_name="创建日期",auto_now=True)

class User(models.Model)

    a = models.OneToOneField(Asset,on_delete=1) # on_delete是级联删除的动作

级联删除

级联删除,例如员工表中一项数据是部门ID,部门ID是部门表的主键,如果是级联删除,当删除了部门A的时候,会把所有属于部门A的员工都给删除。

  • 级联删除的特殊字段
  • models.CASCADE:Django模拟SQL约束ON DELETE CASCADE,并删除包含ForeignKey的对象

注意该CASCADE会有限查找是否有关联数据,先删除管理数据,再删除本条数据.

  • models.PROTECT:抛出ProtectedError以阻止被引用对象的删除
  • SET_NULL:设置ForeignKey为Null,需要指定null=True
代码语言:javascript
复制
from django.db import models

import uuid

# Create your models here.



class UserMit(models.Model):

    # id创建为UUID类型,字段命名为user_id

    id = models.UUIDField(primary_key=True,default=uuid.uuid4,db_column='user_id')

    name = models.CharField(verbose_name="User_name",max_length=20,default="")



class UserId(models.Model):

    name = models.CharField(verbose_name="Test",max_length=15)

    users = models.OneToOneField(UserMit,on_delete=models.CASCADE) # 一对一即users_id 对应 id

一对一映射(创建数据)


  • 无外键约束的模型类UserMit
代码语言:javascript
复制
# 进入Django Shell操作

create1 = UserMit.objects.create(name="henan)
  • 有外键约束的模型类UserId
代码语言:javascript
复制
create2 = UserId.objects.create(name="henan",users=create1) # 通过关联UserMit的实例化对象

create4 = UserId.objects.create(uid="henan",users_id="0dbccd1992474d30a4497b05295e807b") # 关联UserMit表中的user_id对应主键

一对一(查询数据)


正向查询
  • 正向查询:直接通过外键属性查询,则为外键查询
代码语言:javascript
复制
# 通过外键绑定的users_id查询用户,接着上面的创建数据来

>>> a2.id

6

>>> a2.users_id

UUID('43ff679f-42b2-4334-85a0-b493503d6433')
反向查询
  • 没有外键属性的一方,可以调用反向属性查询到关联的另一方
  • 反向关联的属性为实例对象.引用类名(小写)
  • 当反向引用不存在的时候,则会触发异常

当UserId类中定义了外键约束,则UserMit类中会有一个UserId的反向属性

代码语言:javascript
复制
class UserMit(models.Model):

    id = models.UUIDField(primary_key=True,default=uuid.uuid4,db_column='user_id')

    name = models.CharField(verbose_name="User_name",max_length=20,default="")



class UserId(models.Model):

    name = models.CharField(verbose_name="Test",max_length=15)

    users = models.OneToOneField(UserMit,on_delete=models.CASCADE)

>>>  select1 = UserMit.objects.get(name='wlx')

>>> select1.userid.users_id

UUID('c443d1b4-0882-42cb-8659-86ccbd1f8d12')

一对多的映射


一对多是表现现实事物存在的一对多的对应关系,例如一个学校有多个班级,一个班级有多个学生,一本书只能属于一个出版社,一个出版社可以出多本书。

一对多需要明确出具体角色,在多表上设置外键

语法:当一个A类对象可以关联多个B类对象

代码语言:javascript
复制
class ClassRoom(models.Model):

    # 班级唯一

    name = models.CharField("ClassName",max_length=50,unique=True)



class Students(models.Model):

    # 学生多个,可以多个学生在一个班

    student_name = models.CharField("StudentName",max_length=15)

    # 绑定外键约束,属于那个班级

    classroom = models.ForeignKey(ClassRoom,on_delete=models.CASCADE)

一对多映射(创建数据)

有两种方法创建数据,跟上面一对一的一样

代码语言:javascript
复制
class1 = ClassRoom.objects.create(name="高二三班")

Students.objects.create(student_name="XiaoMing",classroom=class1) # 对应外键的属性名,必须传入class对象

Students.objects.create(student_name="Liyang",classroom_id=1) # 对应外键值属性字段,必须传入具体的值

一对多(查询数据)


正向查询
代码语言:javascript
复制
Students.classroom # 直接通过调用外键属性查询

stu = Students.objects.get(id=1)

print(stu.student_name,"的班级是",stu.classroom.name)

XiaoMing 的班级是 高二三班
反向查询[通过ClassRoom查询所有Student]
代码语言:javascript
复制
class1 = ClassRoom.objects.get(name="高二三班")

stu1 = class1.students_set.all() # students_set 是独有的反向属性,获取多个数据,是关联外键的类名小写

for i in stu1:

    print(i.id,i.student_name,i.classroom_id)

多对多映射


多对多表达对象之间多对多的复杂关系,如:每个人都有不同的学校,每个学校都有不同的学生

  • MySQL中创建多对多需要以来第三张表来完成
  • Django中无需手动创建,Django自动完成
  • 语法:在关联的两个类中的任意一个类中models.ManyToManyField(MyModel)
代码语言:javascript
复制
张老师和王老师同时带领高二三班,李老师和王老师都都参与过高三班的课

class ClassRoom(models.Model):

    # 班级唯一

    name = models.CharField("ClassName",max_length=50,unique=True)



class Students(models.Model):

    # 学生多个,可以多个学生在一个班

    student_name = models.CharField("StudentName",max_length=15)

    # 绑定外键约束,属于那个班级

    classroom = models.ForeignKey(ClassRoom,on_delete=models.CASCADE)



class Teacher(models.Model):

    # 教师

    teacher_name = models.CharField("TeacherName",max_length=20,default="")

    name = models.ManyToManyField(ClassRoom)

多对多(创建数据)

方案1:先创建班级,在关联老师

代码语言:javascript
复制
class1 = ClassRoom.objects.create(name="高三九班")

# 张老师和王老师同时带领高二三班

b1 = class1.teacher_set.create(teacher_name="张老师")

b2 = class1.teacher_set.create(teacher_name="王老师")

# 或者

class1.teacher_set.add(b1)

class1.teacher_set.add(b2)
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是关系映射?
  • 一对一映射(创建)
    • 级联删除
      • 一对一映射(创建数据)
        • 一对一(查询数据)
          • 正向查询
          • 反向查询
      • 一对多的映射
        • 一对多映射(创建数据)
          • 一对多(查询数据)
            • 正向查询
            • 反向查询[通过ClassRoom查询所有Student]
        • 多对多映射
          • 多对多(创建数据)
          相关产品与服务
          关系型数据库
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档