013 Django 数据库关系映射

关系映射

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

  1. 一对一映射

    • 如:一个身份证对应一个人
  • 一对多映射

    • 如:一个班级可以有多个学生
  • 多对多映射

    • 如:一个学生可以报多个课程,一个课程可以有多个学生学习
  • 一对一映射

    • 一对一是表示现实事物间存在的一对一的对应关系。

      • 如:一个家庭只有一个户主,一个男人有一个妻子,一个人有一个唯一的指纹信息等
  • 语法: OneToOneField(类名,on_delete=xxx)

    • on_delete 级联删除时要执行的操作

      • models.CASCADE

        • 删除所有包含这个键的对象
        • Django模拟SQL约束ON DELETE CASCADE的行为,删除包含 ForeignKey 的所有对象
  • models.PROTECT

    • 如果其他表引用到了这个外键默认不允许删除
    • modeIs.PROTECT 抛出 ProtectedError阻止被引用对象的删除 [等同于mysq|默认的RESTRICT]
  • SET_NULL

    • 如果想要删除这个外键,那么其他引用了这个外键的值都会被设置为 Null
    • 有一个前提条件,就是被设置 null 的那个引用数据者本身需要能设置为 null(null=True)
  • SET_DEFAULT

    • SET_ DEFAULTForeignKey设置为其默认值
    • 必须设置ForeignKey的默认值
  • class A(model.Model):
        ...
    class B(model.Model):
        属性 = models.OneToOneField(A, on_delete=xxx)
    

    实例

    • 创建一个作者和他们老婆的表

    image-20220625113226313

    • 迁移数据库 migrationsmigrate[这里跳过]

    • 发现我们的外键名字发生了改变,并非是我们命名的 author 而是 author_id

      • image-20220625113409382

    如何创建一个数据?

    • 无外键的情况(正常创建)

      • author1 = Author.objects.create(name='王老师')
        
  • 有外键的情况下

    • # 方案一:关联王老师 obj
      # 此处的 author 需要等于一个 实例化的 obj 对象
      wife1 = Wife.objects.create(name='王夫人',author=author1)
      
  • 方案二:关联王老师对应的主键

    此处 author_id 直接等于一个值即可

    wife1 = Wife.objects.create(name='王夫人',author_id=1)

  • 方案一

    • image-20220625114135397
  • 方案二

    • image-20220625114218524
    • 此处我们 author_id 也可以等于 a2.id
  •  

    查询数据

    1. 正向查询:直接通过外键属性进行查询

      • # 通过 wife 找 author
        from .models import wife
        

    wife = wife.objects.get(name="王夫人")

    print(wife.name,"的老公是", wife.author.name)

  • 反向查询:没有外键属性的一方,可以调用反向属性查询到关联的另一方

    • 反向关联属性为 实例对象.应用类名(小写) 比如作家的反向引用为作家对象.wife

    • 当反向引用不存在的时候会触发异常

    • # 通过author  找  wife 
      from .models import Author
      
  • author1 = Author.objects.get(name="王老师")

    print(author1.name,"的老婆是", author1.wife.name)

     

    一对多映射

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

    创建映射

    • 语法

      • 当一个A类对象可以关联多个B类对象的时候

      • class A(model.Model):
            pass
        

    class B(model.Model):
    属性 = models.ForeignKey( A模型类, on_delete=XXX) #ForeignKey 必须指定on_delete

  • image-20220625120509648

  • 创建数据

    • 先创建 ,再创建

      • from .models import *
        

    pub1 = Publisher.objects.create(name="清华大学出版社")

    使用方法一创建

    Book.objects.create(title="C++",Publisher=pub1)

    使用方法二创建

    Book.objects.create(title="Java",Publish_id=1)

  • image-20220625121619090

  • image-20220625121630133

  • image-20220625121645252

  • 查询数据

    1. 正向查询[通过 Book 查询 Publisher]

      • abook = Book.objects.get(id=1)
        print(abook.title, "的出版社是",abook.publisher.name)
        
      • image-20220625122119273

  • 反向查询 book_set [通过Publisher查询对应的所有的Book]

    • pub1 = Publisher.objects.get(name="清华大学出版社")
      
  • 通过 book_set 方法获取 pub1 对应的多个Book数据对象

    books = pub1.book_set.all()

    print("清华大学出版社的书有:")
    for book in boos:
    print(book.title)

  • image-20220625122147572

  •  

    多对多映射

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

      • mysql中创建多对多需要依赖第三张表来实现
      • Django中无需手动创建第三张表,Django 自动完成
  • 语法:在关联的两个类中的任意一个类中,增加:

    • 属性=models.ManyToManyField(MyModel)
  • 创建映射

    • 一个作者可以出版多本书

    • 一本书可以被多个作者联名编写

      • class Author(models.Model):
            pass
        

    class Book(models.Model):
    authors = models.ManyToManyField(Author)

  • image-20220625122634892

  • 创建数据

    • 方案一 先创建 author 再关联 book

      • author1 =Author.objects.create(name="王老师")
        author2 =Author.objects.create(name="吕老师")
        

    两位老师同时写了一本书

    book11 = author1.book_set.create(title="Python")
    author2.book_set.add(book11)

  • 方案二 先创建 book 再关联 author

    • # 书登场
      book = Book.objects.create(title="python")
      
  • 创建两位老师

    author1 =Author.objects.create(name="王老师")
    author2 = book.authors.create(name="吕老师")

    两位老师都参与了 python 的编写

    book.authors.add(author1)

     

    查询数据

    • 正向查询 有多对多属性的对象查另外一遍

      • 通过 Book 查询对应的所有 Author,此时多对多属性等价于 objects

      • # 获取book对应的所有的author的信息
        book.authors.all()
        

    获取book对应的作者中年龄大于80岁的作者的信息

    book.authors.filter(age__ gt=80)

  • 反向查询

    • 通过 Author 查询对应的所有的 Book,利用反向属性 book_set

    • author.book_set.all( )
      author.book_set.filter( )
      
    •  

  •  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Django是一个高效且功能强大的Web框架,它可以轻松地连接到多种类型的数据库Django支持的数据库类型包括SQLite、MySQL、PostgreSQL、Oracle等。在Django中,我们使用ORM(对象关系映射)来连接数据库,ORM将数据库中的表映射Python中的类,并将表中的每个字段映射Python中的属性。 在Django中,我们需要在settings.py文件中配置数据库连接信息,包括数据库类型、数据库名称、数据库用户名和密码等。配置完成后,我们可以使用Django提供的ORM进行数据库操作,例如创建表、查询数据、插入数据等。 以下是一个简单的Django数据库连接的示例: 1. 在settings.py文件中配置数据库连接信息: ``` DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'mydatabase', 'USER': 'mydatabaseuser', 'PASSWORD': 'mypassword', 'HOST': 'localhost', 'PORT': '3306', } } ``` 2. 创建一个模型类: ``` from django.db import models class Book(models.Model): title = models.CharField(max_length=100) author = models.CharField(max_length=50) pub_date = models.DateField() ``` 3. 在views.py中进行数据库操作: ``` from django.shortcuts import render from .models import Book def book_list(request): books = Book.objects.all() return render(request, 'book_list.html', {'books': books}) ``` 以上代码展示了如何使用Django ORM连接数据库,并使用模型类进行数据操作。如果您有更多关于Django数据库连接的问题,请随时提出,我会尽力为您解答。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值