前期准备

    1. #在进行一系列的表查询的之前,做表
    2. #在models下
    3. from django.db import models
    4. # Create your models here.
    5. class User(models.Model):
    6. name = models.CharField(max_length=32)
    7. age = models.IntegerField()
    8. register_time = models.DateField()
    9. class Book(models.Model):#书
    10. title = models.CharField(max_length=32)
    11. price = models.DecimalField(max_digits=8,decimal_places=2)
    12. publish_date = models.DateField(auto_now=True)
    13. #一对多
    14. publish = models.ForeignKey(to='Publish',on_delete=models.CASCADE)
    15. #多对多
    16. authors = models.ManyToManyField(to='Author')
    17. class Publish(models.Model):#出版社
    18. name = models.CharField(max_length=32)
    19. addr = models.CharField(max_length=32)
    20. email = models.EmailField()
    21. # varchar(254) 该字段类型不是给models看的 而是给后面我们会学到的校验性组件看的
    22. class Author(models.Model):#作者
    23. name = models.CharField(max_length=32)
    24. age = models.IntegerField()
    25. #一对一
    26. authordetail = models.OneToOneField(to='AuthorDetail',on_delete=models.CASCADE)
    27. class AuthorDetail(models.Model):#作者详情
    28. phone = models.BigIntegerField()
    29. addr = models.CharField(max_length=64)

    测试环境准备

    1. """
    2. 当你只是想测试django中的某一个py文件内容 那么你可以不用书写前后端交互的形式
    3. 而是直接写一个测试脚本即可
    4. 脚本代码无论是写在应用下的tests.py还是自己单独开设py文件都可以
    5. """
    6. # 测试环境的准备 去manage.py中拷贝前四行代码 然后自己写两行如果是2.x版本要将def改成if __name__ == "__main__":
    7. import os
    8. import sys
    9. if __name__ == "__main__":
    10. os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day64.settings")
    11. import django
    12. django.setup()
    13. # 在这个代码块的下面就可以测试django里面的单个py文件了

    单表操作

    1. django自带的sqlite3数据库对日期格式不是很敏感 处理的时候容易出错
    2. '''
    3. pk的意义:主键--->可以说是 primary_key 的缩写
    4. pk会自动查找到当前表的主键字段 指代的就是当前表的主键字段
    5. 用了pk之后 你就不需要指代当前表的主键字段到底叫什么了
    6. uid
    7. pid
    8. sid
    9. ...
    10. '''
    11. #增
    12. 方法一:
    13. res = models.User.objects.create(name='wuhu',age=50,register_time=2020-10-5)
    14. 方法二:
    15. ctime = datetime.datetime.now()
    16. user_obj = models.User(name='one',age=15,register_time=ctime)
    17. user_obj.save()
    18. #删
    19. 方法一:
    20. res = models.User.objects.filter(pk=6).delete()
    21. print(res)
    22. 方法二:
    23. user_obj = models.User.objects.filter(pk=5)
    24. user_obj.delete()
    25. #改
    26. 方法一:
    27. res = models.User.objects.filter(pk=4).update(age=21)
    28. 方法二:
    29. user_obj2 = models.User.objects.get(pk=4)
    30. user_obj = models.User.objects.filter(pk=4).first()
    31. user_obj.age=21
    32. user_obj.save()
    33. '''
    34. get和filter 都能拿到对象,前者是直接拿到对象,后者是有个列表套着,需要通过方法取出来
    35. 虽然get比filter方便,能够直接拿到对象,但是如果没有数据对象不存在,就会报错
    36. 而filter不会,他找不到会返回一个空列表,不会报错
    37. 出于程序原则考虑,使用filter
    38. 可以分别print get方法和filter方法来验证
    39. '''

    必知必会方法13条

    1. # 必知必会13条
    2. 1.all() 查询所有数据
    3. 2.filter() 带有过滤条件的查询
    4. 3.get() 直接拿数据对象 但是条件不存在直接报错
    5. 4.first() queryset里面第一个元素
    6. 5.last() queryset里面最后一个元素
    7. 6.values() 可以指定获取的数据字段 --->列表套字典
    8. 7.values_list() 列表套元祖
    9. 8.distinct() 去重
    10. 9.order_by() 排序
    11. 10.reverse() 反转的前提是 数据已经排过序了
    12. 11.count() 统计当前数据的个数
    13. 12.exclude() 排除在外
    14. 13.exists() 基本用不到因为数据本身就自带布尔值 返回的是布尔值
    15. 示范:
    16. # 1.all() 查询所有数据
    17. # 2.filter() 带有过滤条件的查询
    18. # 3.get() 直接拿数据对象 但是条件不存在直接报错
    19. # 4.first() 拿queryset里面第一个元素
    20. # res = models.User.objects.all().first()
    21. # print(res)
    22. # 5.last()
    23. # res = models.User.objects.all().last()
    24. # print(res)
    25. # 6.values() 可以指定获取的数据字段 select name,age from ... 列表套字典
    26. # res = models.User.objects.values('name','age') # <QuerySet [{'name': 'jason', 'age': 18}, {'name': 'egonPPP', 'age': 84}]>
    27. # print(res)
    28. # 7.values_list() 列表套元祖
    29. # res = models.User.objects.values_list('name','age') # <QuerySet [('jason', 18), ('egonPPP', 84)]>
    30. # print(res)
    31. # """
    32. # # 查看内部封装的sql语句
    33. # 上述查看sql语句的方式 只能用于queryset对象
    34. # 只有queryset对象才能够点击query查看内部的sql语句
    35. #
    36. # """
    37. # 8.distinct() 去重
    38. # res = models.User.objects.values('name','age').distinct()
    39. # print(res)
    40. """
    41. 去重一定要是一模一样的数据
    42. 如果带有主键那么肯定不一样 你在往后的查询中一定不要忽略主键
    43. """
    44. # 9.order_by()
    45. # res = models.User.objects.order_by('age') # 默认升序
    46. # res = models.User.objects.order_by('-age') # 降序
    47. #
    48. # print(res)
    49. # 10.reverse() 反转的前提是 数据已经排过序了 order_by()
    50. # res = models.User.objects.all()
    51. # res1 = models.User.objects.order_by('age').reverse()
    52. # print(res,res1)
    53. # 11.count() 统计当前数据的个数
    54. # res = models.User.objects.count()
    55. # print(res)
    56. # 12.exclude() 排除在外
    57. # res = models.User.objects.exclude(name='jason')
    58. # print(res)
    59. # 13.exists() 基本用不到因为数据本身就自带布尔值 返回的是布尔值
    60. # res = models.User.objects.filter(pk=10).exists()
    61. # print(res)

    查看内部sql语句的方式

    1. #方法1:
    2. res = models.User.objects.values_list('name','age')
    3. print(res.query)
    4. #会返回QuerySet对象的查询语句且只有queryset对象才能够点击query查看内部的sql语句
    5. # 方式2:所有的sql语句都能查看
    6. # 去配置文件中配置一下即可
    7. LOGGING = {
    8. 'version': 1,
    9. 'disable_existing_loggers': False,
    10. 'handlers': {
    11. 'console':{
    12. 'level':'DEBUG',
    13. 'class':'logging.StreamHandler',
    14. },
    15. },
    16. 'loggers': {
    17. 'django.db.backends': {
    18. 'handlers': ['console'],
    19. 'propagate': True,
    20. 'level':'DEBUG',
    21. },
    22. }
    23. }

    双下划线查询

    1. #双下划线查询
    2. 注:使用的皆为user
    3. # 1 年龄大于18岁的数据第一个
    4. res = models.User.objects.filter(age__gt=18)
    5. print(res)
    6. # 2 年龄小于35岁的数据
    7. res = models.User.objects.filter(age__lt=35)
    8. print(res)
    9. # 大于等于
    10. res = models.User.objects.filter(age__gte=18)
    11. print(res)
    12. # 小于等于
    13. res = models.User.objects.filter(age__lte=19)
    14. print(res)
    15. # 年龄是18 或者 32 或者40
    16. res = models.User.objects.filter(age__in=[40,18,32])
    17. print(res)
    18. # 年龄在18到40岁之间的 首尾都要
    19. res = models.User.objects.filter(age__range=[18,40])
    20. print(res)
    21. # 查询出名字里面含有s的数据 模糊查询 区分大小写
    22. res = models.User.objects.filter(name__contains='e')
    23. print(res)
    24. # 查询出名字里面含有e的数据 忽略大小写
    25. res = models.User.objects.filter(name__icontains='e')
    26. print(res)
    27. # 查询出注册时间是 2020 1月
    28. res = models.User.objects.filter(register_time__month=10,register_time__year=2021)
    29. print(res)

    一对多外键增删改查

    1. #一对多外键增删改查--->和单表的增删改查类似,只是会多加一个外键
    2. #增
    3. 1 直接写实际字段
    4. models.Book.objects.create(title='中庸',price=85.2,publish_id=1)
    5. models.Book.objects.create(title='安德的游戏',price=85.2,publish_id=2)
    6. models.Book.objects.create(title='死者代言人',price=85.2,publish_id=2)
    7. 2 使用虚拟字段 对象
    8. publish_obj = models.Publish.objects.filter(pk=1).first()
    9. models.Book.objects.create(title='西游记',price=85,pulish=publish_obj)
    10. #删 -->级联删除 和该数据有关的数据都会被删除
    11. models.Publish.objects.filter(pk=1).delect()
    12. #改
    13. 1 直接写实际字段
    14. models.Book.objects.filter(pk=2).update(publish_id=3)
    15. 2 使用虚拟字段 对象
    16. publish_obj = models.Publish.objects.filter(pk=2).first()
    17. models.Book.objects.filter(pk=2).update(publish=publish_obj)

    多对多外键增删改查

    1. #给书籍添加作者
    2. #增
    3. 第一种方式
    4. book_obj = models.Book.objects.filter(pk=2).first()
    5. print(book_obj.authors)#app01.Author.None-->当出现这个None的时候就代表着你已经进入了关系表中
    6. book_obj.authors.add(2) #给id为2的书籍绑定一个主键为2的作者
    7. book_obj.authors.add(2,3)#支持同时添加多个
    8. 第二种方式
    9. author_obj = models.Author.objects.filter(pk=2).first()
    10. author_obj1 = models.Author.objects.filter(pk=3).first()
    11. book_obj.authors.add(author_obj)
    12. book_obj.authors.add(author_obj,author_obj1)
    13. """
    14. add给第三张关系表添加数据
    15. 括号内既可以传数字也可以传对象 并且都支持多个
    16. """
    17. #删
    18. book_obj.author.remove(2)
    19. book_obj.author.remove(2,3)
    20. book_obj.author.remove(author_obj3)
    21. book_obj.author.remove(author_obj2,author_obj1)
    22. """
    23. remove
    24. 括号内既可以传数字也可以传对象 并且都支持多个
    25. """
    26. #改
    27. book_obj.authors.set([1,2]) # 括号内必须给一个可迭代对象
    28. book_obj.authors.set([3]) # 括号内必须给一个可迭代对象
    29. author_obj = models.Author.objects.filter(pk=2).first()
    30. author_obj1 = models.Author.objects.filter(pk=3).first()
    31. book_obj.authors.set([author_obj,author_obj1]) # 括号内必须给一个可迭代对象
    32. '''
    33. 修改就相对特殊一点,他需要迭代对象装着,且改完就会改完全,可以想象成全删了再加上新的
    34. '''
    35. # 清空
    36. # 在第三张关系表中清空某个书籍与作者的绑定关系
    37. book_obj.authors.clear()
    38. """
    39. clear
    40. 括号内不要加任何参数
    41. """

    正反向概念

    1. #正向
    2. #反向
    3. 简单来说 可以把外键字段当正版
    4. 如果我是从有外键字端的表查,我查你就是正向
    5. 如果我在没有外键的字段表查你,我查你就是反向
    6. book ---> 外键字端在书那(正向)--> publish
    7. book <--- 外键字段在书那(反向) <--- piblish
    8. """
    9. 正向查询按字段
    10. 反向查询按表名小写
    11. _set
    12. ...
    13. """

    多表查询
    子查询(基于对象的跨表查询)

    1. # 1.查询书籍主键为1的出版社
    2. book_obj = models.Book.objects.filter(pk=1).first()
    3. res = book_obj.publish
    4. print(res.name)
    5. # 2.查询书籍主键为2的作者
    6. book_obj = models.Book.objects.filter(pk=3).first()
    7. res = book_obj.author------>app01.Author.None-->出现None的时候,就代表不止一个数据,这是时候要用all()方法得到对象
    8. res = book_obj.author.all()
    9. rint(res)
    10. # 3.查询作者jason的电话号码
    11. author_obj = models.Author.objects.filter(name='jason').first()
    12. res = author_obj.authordetail
    13. print(res.phone)
    14. # 4.查询出版社是东方出版社出版的书(正反向)
    15. #正向
    16. publish_obj = models.Publish.objects.filter(name='未来出版社').first()
    17. book_obj = models.Book.objects.filter(publish=publish_obj)
    18. res = book_obj[0]
    19. print(res.title)
    20. #反向
    21. publish_obj = models.Publish.objects.filter(name='未来出版社').first()
    22. book_obj = publish_obj.book_set.all()
    23. print(book_obj)
    24. # 5.查询作者是jason写过的书
    25. #反向
    26. author_obj = models.Author.objects.filter(name='jason').first()
    27. book_obj = author_obj.book_set.all()
    28. print(book_obj)
    29. #正向
    30. author_obj = models.Author.objects.filter(name='jason').first()
    31. book_obj = models.Book.objects.filter(author=author_obj)
    32. print(book_obj)
    33. # 6.查询手机号是110的作者姓名
    34. authordetail_obj = models.AuthorDetail.objects.filter(phone=120).first()
    35. print(authordetail_obj)
    36. author_obj = models.Author.objects-.filter(authordetail=authordetail_obj).first()
    37. print(author_obj.name)
    38. #反向
    39. authordetail_obj = models.AuthorDetail.objects.filter(phone=120).first()
    40. author_obj = authordetail_obj.author
    41. print(author_obj.name)
    42. """
    43. 基于对象
    44. 反向查询的时候
    45. 当你的查询结果可以有多个的时候 就必须加_set.all()
    46. 当你的结果只有一个的时候 不需要加_set.all()
    47. 正向查询也是一样
    48. 且,正向查询一样可以用对象代替,如果我们不知道对象的主键名,而想用正向时就可以用这个方法
    49. 直接举个栗子
    50. 查询作者是jason写过的书
    51. 先查到作者是jason这个对象 author_obj
    52. 然后找书,因为书这个表建有书和作者多对多的关系表,所以直接 author=author_obj 就可以查到
    53. """

    联表查询(基于双下划线的跨表查询)

    1. #基于双下划线的跨表查询
    2. 1.查询jason的手机号和作者姓名
    3. res = models.Author.objects.filter(name='jason').values('authordetail__phone','name')
    4. print(res)
    5. #反向
    6. res =models.AuthorDetail.objects.filter(author__name='jason').values('phone','author__name')
    7. print(res)
    8. 2.查询书籍主键为3的出版社名称和书的名称
    9. res = models.Book.objects.filter(pk=3).values('title','publish__name')
    10. print(res)
    11. #反向
    12. res = models.Publish.objects.filter(book__pk=3).values('name','book__title')
    13. print(res)
    14. 3.查询书籍主键为1的作者姓名
    15. res = models.Book.objects.filter(pk=3).values('author__authordetail__phone','author__name')
    16. print(res)
    17. #反向
    18. res = models.Author.objects.filter(book__pk=3).values('authordetail__phone','name')
    19. print(res)
    20. '''
    21. 简单描述下双下划线的跨表查询
    22. 理论上,表与表之间存在联系,就可以通过双下划线查到
    23. 用法呢也简单
    24. 依旧是正向查询按字段,反向查询按表名小写
    25. 比如我要查书籍主键为1的出版社名称和书的名称,那么书籍的名字就是自己表有的,直接输入字段,出版社名称就跨到出版社表去拿 publish__name
    26. 如果是跨多表查询,建议使用正向,反向查询的话要找中间关系表不然有点麻烦,看第三个题目即可
    27. '''

    思考题目

    1. 今日考题
    2. 1.什么是FBVCBV,能不能试着解释一下CBV的运作原理
    3. FBVfunction base views 就是在视图里使用函数处理请求。
    4. CBVclass base views 就是在视图里使用类处理请求
    5. CBV其实就是FBV 简单来说 CBV要了解三个方法
    6. as_view方法:这个方法只要记住这是个类方法用完之后就是返回view方法
    7. view方法:简单来说就执行dispatch方法
    8. dispatch方法就是根据你前端返回的请求方式,去匹配执行你后端根据不同请求定义的函数方法
    9. 2.模版语法的传值需要注意什么,常见过滤器及标签有哪些
    10. 传值记得如果是传函数或者类这些的话,不需要加括号,前端会自动调用
    11. 常见过滤器:
    12. length
    13. filesizeformat
    14. date
    15. slice
    16. truncatechars
    17. truncatewords
    18. ...
    19. 常见标签
    20. for循环
    21. {% for %}
    22. {% endfor %}
    23. if判断
    24. {% if %}
    25. {% elif %}
    26. {% endif %}
    27. {% empty %}
    28. with起别名
    29. {% with li.4.1.1.key as key %}
    30. <h1>{{ key }}</h1>
    31. {% endwith %}
    32. 3.自定义过滤器,标签,inclusion_tag的流程
    33. 1.在应用下创建一个名字 必须为 templatetags文件夹
    34. 2.在该文件夹内创建任意名称的py文件 --->名字随便起
    35. 3.py文件内必须有以下两句话(一个字符都不能错)
    36. from django import template
    37. register = template.Library()
    38. #自定义过滤器
    39. @register.filter(name='filtername')
    40. #自定义标签
    41. @register.simple_tag(name='tagname')
    42. # 自定义inclusion_tag
    43. @register.inclusion_tag('渲染的html页面')
    44. 4.什么是模版的继承与导入,如何正确使用
    45. 模板的继承意思就是指定一片区域,或者页面,可以直接继承到新页面去,使用去看上一个笔记
    46. 模板导入:将页面的某一个局部当成模块的形式,哪个地方需要就可以直接导入使用即可