ORM 数据库与数据模型类的解耦

  • 一、ORM
    • 1.简介
      • MVC包含了一个重要的框架ORM,实现了数据模型与数据库的解耦
      • 即数据模型的设计不需要依赖于特定的数据库
    • 2.ORM是“对象-关系-映射”的简称,主要任务是:
      • 1)根据对象的类型生成表结构
      • 2)将对象、列表的操作,转换为sql语句
      • 3)将sql查询到的结果转换为对象、列表
  • 二、django模型表的字段与约束
    • 字段
      • CharField  字符串 (必须有字段约束,max_length=整数     表示字符串最大位数)
      • BooleanField 布尔值字段  如果许可空的布尔值输入,换用 NullBooleadField
      • DateTimeField 有时刻的日期字段
      • DecimalField 浮点数字段 (max_digits=最大位数,decimal_places=最大小数位数)
      • IntegerField 整型字段
      • OneToOneField  一对一 映射字段
      • ForignKeyField  外键字段   一对多
      • ManyToManyField  多对多 映射字段
      • AutoField 自动增值的id字段  (primary_key=True  主键约束 为必设置选项)  --》id字段django 自动添加
      • EmailField 邮件字段    必须有max_length约束
      • ImageField 图片字段
      • TextField 备注型字段,用于存储复杂文本
      • URLField 网址字段
      • DateField日期字段    TimeField 时间字段
    • 约束
      • null=True  blank=True    允许为空(这两个约束成对出现)
      • choices  列表选项 设置后,该字段的表单必然会是下拉选择的。这个值必须是一个有小括号构成的元组,每个元组前一个字段将存入数据库,后一个字段是显示给用户看的。
      • 例如 gender = models.CharField(choices=(('girl','女'),('boy','男')),max_length=10)
      • default  默认值
      • unique 设置为 True 启用不存在重复值输入的设定,默认为False
      • verbose_name   后台显示的字段别名
      • max_length 最大输入字符串的长度
      • min_length 最少输入字符串的长度
      • primary_key 主键,设置为 True ,该字段将启用为主键。 默认是 False
      • 详情字段及约束https://blog.csdn.net/qq_41654985/article/details/80689878
  • 三、模型类的创建
    • 在应用文件夹下的models.py
    • from django.db import models
    • from datetime import datetime
    • class StudentInfo(models.Model):
    • #id字段django自动创建
      • name = models.CharField(max_length=20, verbose_name='学生姓名')
      • age = models.IntegerField(verbose_name='学生年龄')
      • gender = models.CharField(choices=(('girl', '女'), ('boy', '男')), default='boy', max_length=10, verbose_name='学生性别')
      • is_delete = models.BooleanField(default=0, verbose_name='是否删除')
      • add_time = models.DateTimeField(default=datetime.now, verbose_name='添加时间')
    • def __str__(self):  #当django查询到表数据,返回的数据对象显示数据对象的name
      • return  self.name
    • class Meta:
      • db_table = 'students'  #不写数据库表名默认为  app名_模型类(小写)  students_studentinfo
      • ordering = ['-name']   #以name字段反序排列数据,不加'-' 以正序排列数据
      • verbose_name_plural = verbose_name    #若未提供该选项, Django 会使用 verbose_name + "s".
      • verbose_name = '学生信息'  #给整个表起别名(后台显示)
  • 四、迁移,同步
    • 1.python manage.py makemigrations   迁移模型类到应用文件夹下的migrations文件夹
    • 2.python manage.py migrate      同步模型类迁移文件到数据库,数据库根据迁移文件建立表
    • 3.每次更改模型类都需重新迁移同步
    • 4.默认django有很多模型类,也需迁移同步
  • 五、模型类数据的增删改查,需导入models.py 下的模型类(StudentInfo)
    • 1.增
      • 1.先实例化模型类对象,对模型类对象的属性赋值,然后save()保存。
        • student=StudentInfo
        • student.字段=值
        • student.save()  -->保存数据并同步到数据库
      • 2. 通过模型默认管理器objects的接口方法create()去创建对象做增加
        • StudnetInfo.objects.create(字段1=值,字段2=值,..)
    • 2.查
      • 通过模型默认管理器objects的接口方法去查找
      • 1.student =StudentInfo.objects.all()
        • 查到所有数据对象,并组成列表的形式,没有数据空列表
      • 2.student = StudentInfo.objects.filter(age=30)
        • 查询到符合条件的数据对象并组成列表,查不到空列表
      • 3.student = StudentInfo.objects.get(age=30)
        • 查询到符合条件的数据对象,查不到报错
        • 一般我们不主张用get方法获取一个对象,因为可能有异常发生,我们可以巧妙的使用filter避免异常,filter返回的是一个数据对象组成的列表,而get返回的直接是这个数据对象。
        • 假设数据库当中只有一条符合条件的数据:我们可以在filter的结果后面加上[0],就代表是get返回的单个数据对象了,并且filter没有数据对象不会发生异常。
    • 3.改
      • 数据的改一般都是建立在查找的基础之上的,当我们需要修改一个数据的时候,都需要先把待修改的数据对象查找到,然后再通过相应的修改方法去修改。
      • 1.student=StudentInfo.objects.filter(name='张三')[0]
        • student.age=31
        • student.save()
      • 2.StudentInfo.objects.filter(name='张三').update(age=31)
    • 4.删
      • 删除一个数据对象和删除一个列表都是可以的
      • 1.student =StudentInfo.objects.filter(name='张三')[0]
        • student.delete()
      • 2.Student.objects.filter(name='张三').delete()
  • 五、多表(1对1关系表)的增删改查
    • 1.关系表的建立
      • class CardId(models.Model):
        • id_number = models.CharField(max_length=10, verbose_name='学生学号')
        • student = models.OneToOneField(StudentInfo, verbose_name='所属学生')   #在子模型类中建立关系字段,这个关系字段到了数据库中变为student_id
        • add_time = models.DateTimeField(default=datetime.now, verbose_name='添加时间')
      • def __str__(self):
        • return self.id_number
      • class Meta:
        • verbose_name = '学号信息'
        • verbose_name_plural = verbose_name
    • 2.如果要增加数据,必须先增加主表数据(StudentInfo),再增加子表(CardId)数据,然后让子表数据和主表数据进行关联
      • 1.子数据对象.关系字段=主数据对象
      • 2.子数据对象.关系字段_id=主数据对象.id
      • 3.各自save()
    • 3.查:
      • 1.①student = StudentInfo.objects.filter(name='张三')[0]   #通过filter拿到主数据对象
        • ②card = student.cardid    #通过主数据对象.子模型类(小写) 拿到子数据对象
        • ③card.id_number   #使用子数据对像拿到他的字段值
      • 2.①card  = CardId.objects.filter(id_number='001')[0]  #通过filer拿到子数据对象
        • ②student = card.student  #通过子数据对象.关系字段  拿到主数据对象
        • ③student.name   #通过主数据对象拿到他的字段值
    • 4.增加数据应该先增加主数据对象,在增加子数据对象
    • 5.删除数据应该先删除子数据对象,在删除主数据对象
    • 详情fiter 过滤查询 方法https://blog.csdn.net/qq_41654985/article/details/80689878
  • 六、多表(一对多关系表)
    • 1.关系表的建立
      • class BanClass(models.Model):
        • name = models.CharField(max_length=20, verbose_name='班级名称')
        • add_time = models.DateTimeField(default=datetime.now, verbose_name='开班时间')
      • def __str__(self):
        • return self.name
      • class Meta:
        • verbose_name = '班级信息'
        • verbose_name_plural = verbose_name
      • class StudentInfo(models.Model):
        • name = models.CharField(max_length=20, verbose_name='学生姓名')
        • age = models.IntegerField(verbose_name='学生年龄')
        • gender = models.CharField(choices=(('girl', '女'), ('boy', '男')), default='boy', max_length=10, verbose_name='学生性别')
        • stu_class = models.ForeignKey(BanClass, verbose_name='所属班级')  #建立一对多的关系字段(外键)
        • is_delete = models.BooleanField(default=0, verbose_name='是否删除')
        • add_time = models.DateTimeField(default=datetime.now, verbose_name='添加时间')
      • def __str__(self):
        • return  self.name
      • class Meta:
        • db_table = 'students'
        • ordering = ['-name']
        • verbose_name = '学生信息'
        • verbose_name_plural = verbose_name
    • 2.主表数据为BanClass  子表数据为StudentInfo
      • 1.子数据对象.关系字段=主数据对象
      • 2.子数据对象.关系字段_id=主数据对象.id
      • 3.①student = StudentInfo.objects.filter(name='张三')[0]   #通过filter拿到子数据对象
        • ②ban = student.stu_class    #通过子数据对象.关系字段 拿到主数据对象
        • ③ban.name   #使用主数据对像拿到他的字段值
      • 4.①ban  = BanClass.objects.filter(name='1ban')[0]  #通过filer拿到主数据对象
        • ②student = ban.student_set.all()  #通过子数据对象.子模型类(小写)_set.all  拿到所有子数据对象(一个班有多个学生)
        • ③遍历列表子数据对象
        • ④通过子数据对象拿到他的字段值

猜你喜欢

转载自blog.csdn.net/qq_41654985/article/details/80690007
今日推荐