美文网首页django
Django-20 关系映射

Django-20 关系映射

作者: JuliusL | 来源:发表于2021-07-17 14:05 被阅读0次
    • 在关系型数据库中,通常不会把所有数据都放在同一张表中,不易于扩展,常见关系映射有:
      1,一对一映射:如身份证对应一个人
      2,一对多映射:一个班级可以有多个学生
      3,多对多映射:一个学生可以报多个课程,一个课程可以有多个学生学习

    1. 一对一

    创建

    • 一对一是表示现实事物间存在的一对一的对应关系。
    • 如:一个家庭只有一个户主,一个男人有一个妻子,一个人有一个唯一的指纹等
    • 语法:OneToOneField(类名, on_delete=xxx)
    class A(model.Model):
      ...
    class B(model.Model):
      属性 = models.OneToOneField(A,on_delete=xxx)
    
    • 特殊字段选项on_delete - 级联删除
      1. models.CASCADE 级联删除。Django模拟SQL约束ON DELETE CASCADE的行为,并删除包含ForeignKey的对象
      2. models.PROTECT 抛出ProtectedError 以阻止被引用对象的删除;(等同于mysql默认的RESTRICT)
      3. SET_NULL设置ForeignKey null; 需要制定null=True
      4. SET_DEFAULT 将ForeignKey设置为其默认值;必须设置ForeignKey的默认值。
        示例:
    from django.db import models
    
    class Author(models.Model):
      name = models.CharField('作家',max_length=50)
    
    class Wife(models.Model):
      name = models.ChartField('妻子',max_length=50)
      author = models.OnToOneField(Author,on_delete=models.CASCADE)
    

    创建数据

    • 无外键的模型类[Author]:
      author1 = Author.objects.create(name='王老师')
    • 有外键的模型类[Wife]:
      关联obj:wife1 = Wife.objects.create(name='王夫人',author=author1)
      关联主键:wife1 = Wife.objects.create(name='王夫人',author_id=1)

    查询数据

    1,正向查询:直接通过外键属性查询,则称为正向查询

    通过wife找author

    from .models import Wife
    wife = Wife.objects.get(name='王夫人')
    wife.author.name
    
    2. 反向查询:没有外键属性的另一方,可以调用反向属性查询到关联的另一方

    反向关联属性为 实例对象.引用类名(小写),如作家的反向引用为 作家对象.wife
    当反向引用不存在时,则会触发异常

    author1 = Author.objects.get(name='王老师')
    author1.wife.name
    

    2. 一对多

    一对多是表示现实事物间存在的一对多的对应关系
    如:一个学校有多个班级,一个班级有多个学生,一本图书只能属于一个出版社,一个出版社允许出版多本图书
    一对多需要明确出具体角色,在多表上设置外键
    当一个A对象可以关联多个B对象时

    class A(model.Model):
    ...
    class B(model.Model):
      属性 = models.ForeignKey("一"的模型类, on_delete=xx)
    

    ForeignKey必须指定on_delete模式

    示例

    from django.db import models
    
    class Publisher(models.Model):
      name = models.CharField('名称',max_length=50,unique=True)
    
    class Book(models.Model):
      title = models.CharField('书名',max_length=50)
      publisher = ForeignKey(Publisher,on_delete=models.CASCADE)
    

    创建数据

    先创建“一”再创建“多”

    from .models import *
    pub1 = Publisher.objects.create('name'='清华大学出版社')
    Book.objects.create(title='C++',publisher=pub1)
    Book.objects.create(title='Java',publisher_id=1)
    

    查询数据

    1,正向查询[通过Book查询Publisher]
    通过publisher属性查询即可

    book.publisher
    abook = Book.objects.get(id=1)
    

    2,反向查询[通过Publisher查询对应的所有Book]
    需要用到反向属性

    pub1= Publisher.objects.get(name='清华大学出版社')
    books = pub1.book_set.all()
    

    多对多

    多对多表达对象之间多对多复杂关系。如:每个人都有不同的学校(小学、初中、高中)每个学校都有不同的学生

    • mysql中创建多对多需要依赖第三张表来实现
    • Django中无需手动创建第三张表,Django自动完成

    语法:在关联的两个类中的任意一个类中,增加

    • 属性 = models.ManyToManyField(MyModel)

    创建数据

    方案1:先创建author再关联book

    author1 = Author.objects.create(name='吕老师')
    author2 = Author.objects.create(name='王老师')
    book11 = author1.book_set.create(title='Python')
    author2.book_set.add(book11)
    

    方案2:先创建book再关联author

    book = Book.objects.create(title='python1')
    author3 = book.authors.create(name='guoxiaonao')
    book.authors.add(author1)
    

    查询数据

    1,正向查询:有多对多属性的对象查另一方
    通过Book查询对应的所有的Author
    此时多对多属性等价于objects
    book.authors.all()->获取book对应的所有author的信息
    book.authors.filter(age__gt=80)->获取book对应的作者中年龄大于80岁的信息
    2,反向查询
    通过Author查询对应的所有Book
    利用反向属性book_set
    author.book_set.all()
    author.book_set.filter()

    相关文章

      网友评论

        本文标题:Django-20 关系映射

        本文链接:https://www.haomeiwen.com/subject/pxmmpltx.html