• Django 07


    今日考题

    1.必知必会N条都有哪些,每个都是干啥使的

    1. models.User.objects.all() # 查询所有数据
    2. models.User.objects.filter() # 带有过滤条件的查询
    3. models.User.objects.get() # 直接拿数据对象,条件不存在直接报错
    4. models.User.objects.all().first() # 拿queryset里面的第一个元素
    5. models.User.objects.all().last() # 拿queryset里面的最后一个元素
    6. models.User.objects.values('name') # 可以指定获取数据字段 相当于select name from ...
    7. models.User.objects.values('name','age').distinct() # 去重一定要去除一模一样的数据,如果带有主
    8. 键那么一定不一样数据
    9. models.User.objects.order_by('age') # 默认升序
    10. models.User.objects.order_by('-age') # 降序
    11. models.User.objects.order_by('age').reverse()# 反转的前提一定是已经排过序
    12. models.User.object.count() # 统计当前数据的个数
    13. models.User.object.exclude(name='jaosn')# 排除在外
    14. models.User.object.filter(pk=1).exist()# 返回布尔值 判断数据对象是否存在

    2.简述神奇的双下划线查询都有哪些方法,作用是什么

    1. 1、年龄大于35岁的数据
    2. res = models.User.objects.filter(age__gt=35)
    3. 2、年龄小于35岁的数据
    4. res = models.User.objects.filter(age__lt=35)
    5. 3、大于等于 小于等于
    6. res = models.User.objects.filter(age__gte=35)
    7. res = models.User.objects.filter(age__lte=35)
    8. 4、年龄是18 或者32 或者40
    9. res = models.User.objects.filter(age__in=[18,32,40])
    10. 5、年龄在1840岁之间 首位都要
    11. res = models.User.objects.filter(age__range=[18,40])
    12. 6、查询名字带有s的数据 模糊查询 区分大小写
    13. res = models.User.objects.filter(name__contains='s')
    14. 不区分大小写
    15. res = models.User.object.filter(name__icontains='s')
    16. 7、查询名字开头结尾是否带有J
    17. res = models.User.objects.filter(name__startswith='j')
    18. res = models.User.objects.filter(name__endswith='j')
    19. 8、查新注册时间是20021
    20. res = models.User.objects.filter(register_time__year='2002')
    21. res = models.User.object.filter(register_time__month='1')

    3.针对多对多外键字段的增删改查方法有哪些,各有什么特点?

    1. # 多对多外键表是第三方表\
    2. # 增
    3. 方法1:直接给定绑定编号
    4. book_obj = models.Book.objects.filter(pk=1).first() # 主键值为1的book对象
    5. book_obj.authors # 进入第三个虚拟表中
    6. book_obj.authors.add(1) # 给主键值为1的book对象绑定主键值为1的作者 (一本书一个作者)
    7. book_obj.authors.add(1,2)# 给主键值为1的book对象绑定主键值为1,2的作者(一本书两个作者)
    8. 方法二:虚拟字段,绑定对象
    9. author_obj = models.Author.objects.filter(pk=1).first() # 主键值为1的author对象
    10. book_obj.authors.add(author_obj)
    11. '''
    12. add() 给第三方表传数字也可以是对象,并且都支持多个
    13. '''
    14. # 删
    15. book_obj.authors.remove(1) # 删除给book对象绑定的单个作者
    16. book_obj.authors.remove(1,2) # 删除给book对象绑定的多个作者
    17. '''
    18. remove()就可以传对象 也可以传数字
    19. '''
    20. # 修改
    21. book_obj.authors.set([1,2]) # 括号内必须给一个可迭代对象
    22. 虚拟对象方式
    23. author_obj = models.Author.objects.filter(pk=2).first()
    24. book_obj.authors.set([author_obj])
    25. '''
    26. 括号内必须传一个可迭代对象,该对象既可以是数字,也可以是对象,并且都支持多个
    27. '''
    28. # 清空
    29. 清空第三方表中书籍与某些作者的第三方关系
    30. book_obj.authors.clear() # 清空主键字段为1的书籍与作者的绑定关系
    31. '''
    32. clear()括号内不加任何参数
    33. '''

    4.什么是正反向的概念,及查询口诀,你能否总结一下正反向查询不同情况下点击不同字段的规律

    1. # 正向
    2. 外键字段在我手上,我查你就是正向
    3. # 反向
    4. 外键字段不在我手上,我查你就是反向
    5. eg:
    6. Book 外键字段在书在(正向)>> Publish
    7. Publish 外键字段是书(反向)>>> Book
    8. '''
    9. 一对一和多对多的正反向查询也是如此
    10. 口诀:正向查询按字段 反向查询按表明小写 --set
    11. '''

    上周内容回顾

    单表的增删改查

    1. # 增
    2. 1.create()
    3. 2.对象.save()
    4. # 查
    5. 1. all() 查所有
    6. 2. 筛选条件,括号内多个参数之间逗号隔开 并且默认是and关系
    7. 3. get() 条件不存在直接报错 不推荐使用
    8. # 改
    9. update() queryset对象帮你封装的批量更新
    10. 对象.save()
    11. # 删
    12. delete() queryset对象帮你封装的批量删除
    13. 对象.delete()
    14. '''
    15. 在实际项目中数据是不可能真正删除的 一般情况下都用一个字段来标记是否删除
    16. '''

    测试环境准备

    1. # 你如果只想测试django某一py文件(大部分情况下就是models.py)
    2. # 在应用下的tests.py或者自己新建一个py文件
    3. '''
    4. 1.去manage.py拷贝前四行
    5. 2.自己书写两行
    6. import django
    7. django.setup()
    8. '''

    如何查看ORM内部的sql语句

    1. # 1.queryset对象可以直接点query查看
    2. queryset对象.query
    3. # 2.配置文件配置日志相关代码即可(不用记,直接复制粘贴)
    4. LOGGING = {
    5. 'version': 1,
    6. 'disable_existing_loggers': False,
    7. 'handlers': {
    8. 'console':{
    9. 'level':'DEBUG',
    10. 'class':'logging.StreamHandler',
    11. },
    12. },
    13. 'loggers': {
    14. 'django.db.backends': {
    15. 'handlers': ['console'],
    16. 'propagate': True,
    17. 'level':'DEBUG',
    18. },
    19. }
    20. }

    必知必会N多条

    1. # 1.all() 查看所有数据
    2. # 2.filter() 我们在利用主键字段筛选数据的时候,可以不考虑主键字段叫什么,直接使用pk代替
    3. # 3.get() 筛选条件不存在直接报错
    4. # 4.values() 获取指定字段的数据 返回结果是一个queryset对象(列表套字典的形式)
    5. # 5.values_list() 获取指定字段对应的数据 返回结果是一个queryset对象(列表套元组的形式)
    6. # 6.count() 统计查询出来的数据个数
    7. # 7.first()
    8. # 8.last()
    9. # 9.order_by() 默认是升序 你可以在字段前面加一个-变成降序
    10. # 10.reverse() 前面已经是排序过了 之后在反转
    11. # 11.exclude() 排除...在外
    12. # 12.distinct() 去重(主键一定不要忘记)
    13. # 13.exists() 判断数据值是否有值 返回布尔值

    神奇的双下划线查询

    1. # 价格大于 小于 大于等于 小于等于
    2. prince__gt
    3. prince__lt
    4. prince__gte
    5. prince__lte
    6. # 成员运算
    7. prince__in
    8. # 范围查询
    9. prince__range
    10. # 模糊查询
    11. title__contains 默认是区分大小写
    12. title__icontains 忽略大小写
    13. # 只按照年份或者月份或者
    14. create_time__yaer
    15. cretae_time__month

    外键字段的增删改查

    1. # 一对多
    2. publish_id = 1
    3. publish = publish_obj
    4. # 多对多
    5. add
    6. remove
    7. 上述两个方法括号内既可以传对象也可以传数字并且都支持多个
    8. set 括号内必须传一个可迭代对象 可迭代对象里面可以是数字也可以是对象并且都支持传多个
    9. clear 括号内无需给任何参数 直接清空对应的数据关系

    多表查询

    1. # 正反向概念
    2. 正向 外键字段就在我手中
    3. 反向 外键字段不在我手中
    4. #小口诀
    5. 正向查询按外键字段 反向查询按表明小写
    6. _set
    7. .all()
    8. # 温馨提示
    9. 书写sql语句和orm语句一样 不要试图一次性写完 可以分步写
    10. '''
    11. 多表操作
    12. 1.子查询
    13. 2.联表操作
    14. inner join
    15. left join
    16. right join
    17. union
    18. Django orm中
    19. 1 基于对象的跨表查询
    20. 子查询
    21. 先拿到一个数据对象 然后点点点
    22. 2 基于双下划线的跨表查询
    23. 联表查询
    24. '''
    25. 1.基于对象的跨表查询
    26. book_obj.publish
    27. book_obj.authors.all()
    28. author_obj.author_detail
    29. publish_obj.book_set.all()
    30. author_obj.book_set.all()
    31. 2.基于上下划线的跨表查询
    32. models.Book.objects.filter(pk=1).values('title','publish__name')
    33. models.Publish.objects.filter(pk=1).values('book_title','name')
    34. # 利用双下划线的跨表查询可以帮助你跨n多张表 只要有外键字段
    35. models.Book.objects.filter(pk=1).values('authors__author_detail__phone')

    今日内容概要

    • 聚合查询(聚合函数的使用)
    • 分组查询的使用
    • F与Q查询
    • django中如何开启事物
    • orm中常用字段及参数
    • 数据库查询优化(only与defer、select_related与prefetch_related)
    • 图书管理系统作业讲解

    今日内容详细

    聚合查询

    1. # 聚合查询 aggregrate
    2. '''
    3. 聚合查询通常情况下都是配合分组一起使用的
    4. 只要是跟数据库相关的模块基本上都在django.db.models
    5. 如果没有也应该在django.db里面
    6. '''
    7. from app01 import models
    8. from django.db.models import Max,Min,Sum,Count,Avg
    9. # 1 查询所有书的平均价格
    10. res = models.Book.objects.aggregate(Avg('price'))
    11. print(res)
    12. # 2.聚合方法一次性使用
    13. res=models.Book.objects.aggregate(Max('price'),Min('price'),Sum('price'),Count('price'),Avg('price'))
    14. print(res)

    分组查询

    1. # 分组查询 annotate
    2. '''
    3. mysql分组查询有那些特点
    4. 分组之后默认只能获取到分组的依据 组内其他字段都无法直接获取
    5. 严格模式
    6. ONLY_FULL_GROUP_BY
    7. '''
    8. # 1、统计每一本书的作者个数
    9. res = models.Book.objects.annotate(author_num=Count('authors')).values('title','author_num')
    10. print(res)
    11. models后面点书就按照书分组,author_num是我们自己定义的字段 用来存储统计出来的每本书对应的作者个数
    12. '''
    13. 代码没有补全不要怕正常写 补全是pycharm给你的 后面到服务器上面直接书写代码 什么补全都没有
    14. '''
    15. # 2.统计每个出版社卖的最便宜的书的价格
    16. res = models.Publish.objects.annotate(min_price=Min('book__price')).values('name','min_price')
    17. print(res)
    18. # 3.统计不止一个作者的图书(先按照图书分组,求每一本书对应的作者个数,过滤出不止一个作者的图书)
    19. res = models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1).values('title','author_num')
    20. print(res)
    21. '''
    22. 只要你的orm语句结果还是一个queryset对象那么他就可以无限制的点queryset对象封装的方法
    23. '''
    24. # 4.查询每个作者出的书的总价格
    25. res = models.Author.objects.annotate(sum_price=Sum('book__price')).values('name','sum_price')
    26. print(res)
    27. '''
    28. 如果我想要按照指定的字段如何处理呢?
    29. models.Book.objects.values('price').annotate()
    30. '''

    F与Q查询

    1. # F查询
    2. from django.db.models import F
    3. '''
    4. 能帮助你直接获取表中的某个数据
    5. 在操作字符类型数据的时候 F不能够做到字符串的拼接
    6. '''
    7. # 1、查询卖出数大于库存数的书籍
    8. res = models.Book.objects.filter(maichu__gt=F('kucun')).first()
    9. print(res.title)
    10. # 2.将所有的书籍价格提高500元
    11. res = models.Book.objects.update(price=F('price')+500)
    12. # 3.将所有书的后面名称都加上爆款两字
    13. from django.db.models.functions import Concat
    14. from django.db.models import Value
    15. res = models.Book.objects.update(title=Concat(F('title'),Value('爆款')))
    16. res = models.Book.objects.update(title=F('title')+'爆款') #所有名称都会变成空白
    17. # Q查询
    18. # 1.查询卖出数大于800 价格小于800的书籍
    19. # res = models.Book.objects.filter(maichu__gt=800,price__lt=900)
    20. # print(res)
    21. '''
    22. filter括号内多个参数之间是and关系
    23. '''
    24. from django.db.models import Q
    25. # res = models.Book.objects.filter(Q(maichu__gt=800),Q(price__lt=900)) #Q包裹逗号分割 还是and关系
    26. # res = models.Book.objects.filter(Q(maichu__gt=800)|Q(price__lt=900)) #| or关系
    27. # res = models.Book.objects.filter(~Q(maichu__gt=800)Q(price__lt=900)) #~ not关系
    28. # print(res)
    29. # Q的高阶用法 能够将查询条件的左边也变成字符串的形式
    30. q = Q()
    31. # q.connector = ’or‘ 修改默认关系变成or
    32. q.children.append(('maichu__gt',800))
    33. q.children.append(('price__lt',900))
    34. res = models.Book.objects.filter(q) # 默认是and关系
    35. print(res)

    django中如何开启事物

    1. '''
    2. 事物
    3. ACID
    4. 原子性:不可分割的最小单位
    5. 一致性:跟原子性相辅相成
    6. 隔离性:事物之间互相不干扰
    7. 持久性:事物一旦确定永久生效
    8. 事物的回滚 rollback
    9. 事物的确认 commit
    10. # 目前你只需要简单的开启事物
    11. from django.db import transaction
    12. transaction.atomic():
    13. sql语句
    14. 在with代码块内书写的所有orm操作都属于同一个事物

    orm中常用字段及参数

    1. AutoFiled int自增列 必须填入参数 primary_key=True。当model中没有自增列,则自动会创建一个列名为id的列
    2. InterField int
    3. BigInterField bigint
    4. CharField 字符类型varchar 必须提供max_length参数,表示长度
    5. DateField 日期字段
    6. DateTimeField 日期时间字段
    7. 参数:auto_now每次修改数据的时候都会更新时间
    8. auto_now_add 只在创建数据的时候记录创建时间后续不会自动修改
    9. BooleanField(Field) 布尔值类型
    10. 该字段传布尔值(False/True) 数据库里面存10
    11. TextField(Field) 文本类型
    12. 该字段可以用来存大段文本内容 没有字数限制
    13. FileField(Field) 字符类型
    14. upload_to = '/data'
    15. 给该字段传一个文件对象,会自动将文件保存到/data目录下然后将文件路径保存到数据库中
    16. /data/a.txt
    17. #django除了给你提供很多字段类型之外 还支持你自定义字段类型
    18. # 字段参数
    19. null 用于表示某个字段可以为空
    20. unique 如果设置unique=True 表示该字段再此表中是唯一的
    21. db_index 如果db_index=True 则代表着为此字段设置索引
    22. default 为该字段设置默认值
    23. # 关系字段
    24. ForeignKey
    25. 外键类型在ORM中用来表示外键关联关系,一般把ForeignKey字段设置在 '一对多''多'的一方。
    26. ForeignKey可以和其他表做关联关系同时也可以和自身做关联关系。
    27. 字段参数
    28. to 设置要关联的表
    29. to_field 设置要关联表的字段
    30. on_delete 当删除关联表中的数据时
    31. db_constrains 是否在数据库中创建外键的约束,默认为True
    32. class MyModel(models.Model):
    33. user = models.ForeignKey(
    34. to="User",
    35. to_field="id"
    36. on_delete=models.SET(func)
    37. )
    38. OneToOneFiled
    39. 一对一字段。
    40. 通常一对一字段用来扩展已有字段。(通俗的说就是一个人的所有信息不是放在一张表里面的,简单的信息一张表,隐私的信息另一张表,之间通过一对一外键关联)

    数据库查询优化

    1. only 与 defer
    2. select_related与prefetch_related
    3. '''
    4. orm语句的特点
    5. 惰性查询
    6. 如果你仅仅只书写了orm语句 在后面根本没有用到该语句查询出来的参数 那么orm会自动识别 不执行
    7. '''
    8. # 想要获取书籍表中所有书的名字
    9. # res = models.Book.objects.values('title')
    10. # for d in res:
    11. # print(d.get('title'))
    12. # 你给我实现获取到的是一个数据对象,然后点title就能拿到书名 并且没有其他字段
    13. # res = models.Book.objects.only('title')
    14. # print(res)
    15. # for i in res:
    16. # print(i.title) # 点击only括号内的字段不会走数据库
    17. # print(i.price) # 点击only括号外的字段会重新走数据库查询
    18. # res = models.Book.objects.defer('title') #对象除了没有title属性其他都有
    19. # print(res)
    20. # for i in res:
    21. # print(i.title) # 点击defer括号内的字段重新走数据库查询
    22. # print(i.price) # 点击defer括号外的字段不会走数据库
    23. '''
    24. defer与only刚好相反
    25. defer括号内放的字段不在查询出来的对象里面 查询该字段需要重新走数据库
    26. 而如果查询非括号内的字段不需要走数据库
    27. '''
    28. # res = models.Book.objects.all() # 每循环一次就要走一次数据库查询
    29. # for i in res:
    30. # print(i.publish.name)
    31. # res = models.Book.objects.select_related('publish')
    32. '''
    33. select_related内部现将book与publish连起来 然后将大表里面的所有数据对象全部封装给查询出来的对象
    34. 这个时候对象无论是点击book表中的数据还是publish表中的数据都无需再走数据库查询 网络请求越少延迟越低 也就是优化数据库查询
    35. select_related括号内只能放外键字段 一对一 一对多 多对多也不行
    36. '''
    37. # print(res)
    38. # for i in res:
    39. # print(i.publish.name)
    40. res = models.Book.objects.prefetch_related('publish')
    41. for i in res:
    42. print(i.publish.name)
    43. '''
    44. prefetch_related该方法内部就是子查询
    45. 将子查询出来的所有结果也给你封装到对象中
    46. 给你的感觉也好像是一次性搞定
    47. '''

  • 相关阅读:
    【什么是区块链】
    荷兰国旗问题到快排的实现
    《UnityShader入门精要》学习2
    Jsoup解析XML文件
    2023秋招,Java岗最全面试攻略,吃透25个技术栈Offer拿到手软!
    【网络通信】探索UDP与TCP协议、IP地址和端口号的奥妙
    算法通过村第十一关-位运算|白银笔记|高频题目
    数据结构栈和队列
    如何实现FinClip微信授权登录的三种方案
    vant实现Select效果--单选和多选
  • 原文地址:https://blog.csdn.net/m0_59882269/article/details/126153294