Django ORM学习

8 篇文章 0 订阅

Django ORM

重点:对对象操作,结果体现在数据库上。

不修改表的结构的话,不需要make migrations 和make migrate

  1. models.py 编写模型类

    • 数据库和类之间的桥梁

    • 类–表 对象–记录 属性–字段

    • 模型类名==表名 继承models.Model

    • 模型类字段 :mysql每种类型与models模块一一对应,例如 varchar 对应models.CharField()

    • 关系型字段

      • 一对一
        • 助教和教师一对一
        • 在助教表中,添加字段teacher = models.OneToOneField(Teacher,on_delete = models.SET_NULL,null=True,blank=True)
        • 教师删除时,字段置空
      • 一对多 对应外键
        • 教师和课程一对多
        • 课程表中,添加字段 teacher = modules.ForeignKey(Teacher,on_delete=models.CASCADE)
        • Teacher是teacher类名,添加删除级联
      • 多对多
        • 学生和课程多对多关系
        • 学生表中,添加字段 course = models.ManyToManyField(Course)
        • Django会生成关联表courses_student_course
    • 字段参数 name = models.CharField(db_column = “age” ) 改变字段名为age,其他属性类似。如果在teacher app下的的user类,表名就是teacher_user

    • 可以自关联,第一个参数写self或者类名。比如地址表可以有 省 城市 区记录,城市关联到省,区关联到城市。

    • 元数据Meta

      • 在类表中 class Meta:

      ​ db_table = “address” #表名

      ​ ordering = ‘pid’ #排序

      ​ unique_together = (‘address’,‘note’) #两个字段不能同时相同

    • 在子表中定义外键

  2. Django中更改数据表

    • make migrations 创建数据库执行的sql语句,在migrations 文件夹下
    • make migrate 执行migrations 中的文件,创建表
  3. Django导入数据到数据库

    • 命令行
      • python3 manage.py shell
      • from courses.models import Teacher #要插入的表所对应的类
      • t = Teacher(nickname=‘Jack’) #创建对象
      • t.save() #保存到数据库
      • exit
    • python脚本
    • 数据库
    • fixture序列化
  4. Django导出数据(略)

Models API

  1. 查询 返回新的QuerySet

    • 相关API

    • QuerySet 查询集

    • fans nickname均为Teacher类的属性

      1. Teacher.objects.all() # 返回所有结果
      1. Teacher.objects.filter(fans__gte=500) # QuerySet可以是多条结果,返回粉丝数大于等于500
    • Teacher.objects.filter(fans_in=[666,1231]) # in操作

      1. Teacher.objects.get(nickname = ‘Jack’) # get()只能返回一条结果
    • 使用切片 Teacher.objects.all() [:1]

      1. 排序 Teachers.objects.all().order_by(‘fans’) #升序排列 '-fans’降序排列
    • 链式查询 Teacher.objects.filter(fans__gte=500).order_by(‘fans’) #先查询fans大于500,再升序排列

    • 查看原生sql语句 : str(Teacher.objects.all().query)

    • Teacher.objects.all().exclude(nickname = ‘Peter’) 在结果集中去除

      1. Teacher.objects.all().reverse() 结果集反向排序
      • 需要在Meta元数据中添加ordering
      1. distinct()
    • 实现字段别名,排除字段,选择字段

      • 别名 Student.objects.all().extra(select={‘name’:‘nickname’}) # 将对象属性名由nickname改为name
      • Student.objects.all().only(‘nickname’,‘age’) # 只查询nickname,age属性
    • 获取字典或元组类型的QuerySet

      • Student.objects.values(‘nickname’,‘age’) # 返回值为字典列表,key为nickname,age
      • Student.objects.values_list(‘nickname’,‘age’) #返回值是元组列表,每个元组是(nickname,age)对
        • Student.objects.values_list(‘nickname’,flat = True) #返回值是列表
    • 根据日期时间查询

      • dates()
      • datetimes()
    • 集合运算

        • p1 = Course.objects.filter(price__gte=240)
        • p2 = Course.objects.filter(price__lte=260)
        • p1.union(p2)
        • intersection()
        • difference()
    • 查询优化

      • 一对多(外键) select_related()
        • Course.objects.all().select_related(‘teacher’) #teacher是外键
      • 多对多 prefetch_related()
        • 根据学生查找所选课程
        • students = Student.objects.filter(age__lt=30).prefetch_related(‘course’)
        • for s in students:
          • print(s.course.all())
    • 反向查询

      • 通过老师(父表)查询课程(子表),查询老师所教的课程
      • Teacher.objects.get(nickname=‘Jack’).course_set.all() #course_set代表course表
    • 聚合

      • .annotate
      • Course.objects.values(‘teacher’).annotate(vol=Sum(‘volume’)) # 返回字典列表,每个字典有教师姓名(因为在Course类中存储的teacher就是姓名)和课程volume属性的求和
      • Avg求平均值
    • row()执行sql原生语句

  2. 不返回QuerySet的API

    • 获取对象 仅一条数据(in_bulk除外)
      • get() 指定id
      • get_or_create() 获取或创建
      • first() 第一条
      • last() 最后一条
      • earliest() 最早创建
      • latest() 最晚创建
      • in_bulk() 批量返回对象,列表传入主键值
        • Courses.objects.in_bulk([‘course1’,‘course2’])
    • 创建对象
      • create() 单个创建
      • bulk_create() 批量创建
      • update_or_create() 创建或更新
    • 更新对象
      • update() 更新
        • Course.objects.filter(title=‘Java教程’).update(price=300)
      • update_or_create() 创建或更新
    • 删除对象
      • delete() 使用filter过滤
      • Course.objects.filter(title=‘test’).delete()
    • 其它操作
      • exists() 查询是否存在,返回bool
      • count() 返回记录数
      • aggregate() 聚合,返回得到的值而不是记录
        • Course.objects.aggregate(Max(‘price’),Avg(‘price’),Sum(‘volume’))
  3. 自定义聚合查询

    实现group_concat

F对象和Q对象

  1. F对象:操纵数据
    • Course.objects.update(price=F(‘price’)-11) # 对所有课程价格-11
    • 对两个字段进行比较
      • Course.objects.filter(volume_lte=F(‘price’)*10) # 销量小于价格*10
  2. Q对象:操纵关系 & | ~
    • 同时满足title包含java且销量大于5000 #双下划线
      • Course.objects.filter(Q(title_ _icontains=‘java’)&Q(volume__gte=5000))
      • | 和 ~用法相同
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值