• Django 06


    每日测试

    1.什么是FBV与CBV,能不能试着解释一下CBV的运作原理

    FBV(function base views)就是在视图里面使用函数处理请求

    CBV(class base views)就是在视图里面使用类处理请求

    能够根据请求方式的不同自动匹配触发对应方法的执行(只要是视图函数都应该有一个形参request)

    urls.py FBV CBV在路由匹配上本质上都是一样的,路由对应函数内存地址

    url(r'^index/',views.index)   FBV

    url(r'^index/',views.Myindex.as_view())  CBV

    CBV的精髓

    def dispatch(*args,**kwargs):
      if request.method.lower() in ['get','post',...]:
            handler = getattr(self,request.method.lower(),'报错信息')
      else:
            handler = '报错提示方法'
      return handler(request,*args,**kwargs)

    Django的url是将一个请求分配给可调用的函数的,而不是一个class。针对这个问题,class-based view提供了一个as_view()静态方法(也就是类方法),调用这个方法,会创建一个类的实例,然后通过实例调用dispatch()方法,dispatch()方法会根据request的method的不同调用相应的方法来处理request(如get() , post()等)。到这里,这些方法和function-based view差不多了,要接收request,得到一个response返回。如果方法没有定义,会抛出HttpResponseNotAllowed异常。

    2.模版语法的传值需要注意什么,常见过滤器及标签有哪些

    变量相关 {{}}

    逻辑相关{%%}

    要知道render支持两种给html页面传值的方式

    python所有的基本数据类型 函数名 类名 对象 都可以被传到html页面上

    针对函数名和类名模板语法会自动加括号调用(但是不支持额外的参数)

    在前端页面模板语法如何获取容器类型里面的数据   统一采用‘句点符’

    d.key

    l.3

    ...

    过滤器语法结构

    {{数据|过滤器:参数}}

    |length
    |default
    |filesizeformat
    |date:'Y-m-d'
    |slice:'0:6:2'
    |truncatechars(包含三个点)
    |truncatewords(不包含三个点 按空格切)
    |add
    |cut
    |join
    |safe

    转义
        # 前端
          |safe
      # 后端
          from django.utils.safestring import mark_safe
        res = mark_safe('

    baby

    ')
    """
    前端代码不一定非要在html页面上书写,也可以在后端生成然后传递给html页面!!!
    """

    标签

    for循环

    {% for i in l %}
        {{ forloop }}
      {% empty %}
              可迭代对象里面没有元素 没法for循环的时候自动走empty
    {% endfor %}

    if 判断

    {% if user %}
        
    {% elif age %}
        
    {% else %}

    {% endif %}

    with起别名

    {% with data.0.name.1.password.2.heiheihei as t%}
        {{ t }}
    {%endwith%}
     

    3.自定义过滤器,标签,inclusion_tag的流程

    1 创建一个templatetags文件夹 在其下面创建任意名字的py文件(mytag.py)

    在文件内书写两行代码

    from django import template
    register = template.Library()

    自定义过滤器

    @register.filter(name='名字')

    def index(v1,v2):

            return v1+v2

    自定义标签

    @register.simple_tag(name='名字')

    def reg(*args):

            pass

    自定义inclusion_tag

    @register.inclusion_tag(name='名字')

    def bar(n):

            return {}

    如何使用上述三者

    {% load mytag%}

    {{n|名字:'参数'}}

    {%名字 参数1 参数2 参数3 参数4%}

    {%bar%}

    4.什么是模版的继承与导入,如何正确使用

     继承   {% extends 'myhtml.html' %}

    局部修改  

            先去模板页面中划定可以修改的内容

            {% block content%}

            模板内容

            {% endblock%}

    模板的导入 {% include ‘模板html文件’%}

    今日内容概括

    模板层(ORM语法)跟数据库打交道

            单标查询(增删改查)

            常见的十几种查询方法

            神奇的双下划线查询

            多表操作

            外键字段的增删改查

            跨表查询(重点)

                    子查询

                    连表查询

            聚合查询

            分组查询

            F与Q查询

    今日内容详细

      单表查询(增删改查)

    1. from app01 import models
    2. # 增
    3. # res = models.User.objects.create(name='json',age=12,register_time='2002-2-12')
    4. # print(res) # User object
    5. #
    6. # import datetime
    7. # ctime = datetime.datetime.now()
    8. # user_obj = models.User(name='engo',age=18,register_time=ctime)
    9. # user_obj.save()
    10. # 删
    11. # user_obj = models.User.objects.filter(pk=2).delete
    12. # user_obj = models.User.objects.filter(pk=1).first().delete()
    13. '''
    14. pk会自动找到当前表的主键字段 指代的就是当前表的主键字段
    15. 用了pk之后你就无需知道当前主键字段的名字了
    16. '''
    17. # 修改
    18. # models.User.objects.filter(pk=3).update(name='egonNB')
    19. # res = models.User.objects.get(pk=3) # User object
    20. # res1 = models.User.objects.filter(pk=3)# ]>
    21. # print(res,res1)
    22. # res.name = 'egonPPP'
    23. # res, save()
    24. '''
    25. get方法返回的直接就是当前的数据对象 但是该方法不推荐使用
    26. filter方法返回的是一个queryset数据对象 若表对象不存在的时候不会报错
    27. '''

    测试脚本

    1. """
    2. 当你只是想测试django中的某一个py文件内容 那么你可以不用书写前后端交互的形式
    3. 而是直接写一个测试脚本即可
    4. 脚本代码无论是写在应用下的tests.py还是自己单独开设py文件都可以
    5. """
    6. # 测试环境的准备 去manage.py中拷贝前四行代码 然后自己写两行
    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文件了

    必知必会13条

    1. # res = models.User.objects.all() # 查询所有数据
    2. # res = models.User.objects.filter() # 带有过滤条件的查询
    3. # res = models.User.objects.get() # 直接拿数据对象 但是条件不存在直接报错
    4. # res = models.User.objects.all().first() # 拿queryset里面的第一个元素
    5. # res = models.User.objects.all().last() # 拿queryset里面的最后一个元素
    6. # res = models.User.objects.values('name') # 可以指定获取的数据字段 select name form ...
    7. # < QuerySet[{'name': 'egonNB'}, {'name': 'json'}, {'name': 'engo'}, {'name': 'json'}, {'name': 'engo'}] > 是一个列表套字典的形式
    8. # res = models.User.objects.values_list('name') # SELECT `app01_user`.`name` FROM `app01_user`
    9. # < QuerySet[('egonNB',), ('json',), ('engo',), ('json',), ('engo',)] > 列表套元组的形式
    10. # 8.distinct() 去重
    11. # res = models.User.objects.values('name','age').distinct()
    12. # print(res)
    13. """
    14. 去重一定要是一模一样的数据
    15. 如果带有主键那么肯定不一样 你在往后的查询中一定不要忽略主键
    16. """
    17. # 9.order_by()
    18. # res = models.User.objects.order_by('age') # 默认升序
    19. # res = models.User.objects.order_by('-age') # 降序
    20. #
    21. # print(res)
    22. # 10.reverse() 反转的前提是 数据已经排过序了 order_by()
    23. # res = models.User.objects.all()
    24. # res1 = models.User.objects.order_by('age').reverse()
    25. # print(res,res1)
    26. # 11.count() 统计当前数据的个数
    27. # res = models.User.objects.count()
    28. # print(res)
    29. # 12.exclude() 排除在外
    30. # res = models.User.objects.exclude(name='jason')
    31. # print(res)
    32. # 13.exists() 基本用不到因为数据本身就自带布尔值 返回的是布尔值
    33. # res = models.User.objects.filter(pk=10).exists()
    34. # print(res)

    查看内部sql语句的方式

    1. # 方式1
    2. res = models.User.objects.values_list('name','age') #
    3. print(res.query)
    4. 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. # 1 年龄大于35岁的数据
    3. # res = models.User.objects.filter(age__gt=35)
    4. # print(res)
    5. # 2 年龄小于35岁的数据
    6. # res = models.User.objects.filter(age__lt=35)
    7. # print(res)
    8. # 大于等于 小于等于
    9. # res = models.User.objects.filter(age__gte=32)
    10. # print(res)
    11. # res = models.User.objects.filter(age__lte=32)
    12. # print(res)
    13. # 年龄是18 或者 32 或者40
    14. # res = models.User.objects.filter(age__in=[18,32,40])
    15. # print(res)
    16. # 年龄在18到40岁之间的 首尾都要
    17. # res = models.User.objects.filter(age__range=[18,40])
    18. # print(res)
    19. # 查询出名字里面含有s的数据 模糊查询
    20. # res = models.User.objects.filter(name__contains='s')
    21. # print(res)
    22. #
    23. # 是否区分大小写 查询出名字里面含有p的数据 区分大小写
    24. # res = models.User.objects.filter(name__contains='p')
    25. # print(res)
    26. # 忽略大小写
    27. # res = models.User.objects.filter(name__icontains='p')
    28. # print(res)
    29. # res = models.User.objects.filter(name__startswith='j')
    30. # res1 = models.User.objects.filter(name__endswith='j')
    31. #
    32. # print(res,res1)
    33. # 查询出注册时间是 2020 1月
    34. # res = models.User.objects.filter(register_time__month='1')
    35. # res = models.User.objects.filter(register_time__year='2020')

    多表操作前期准备

    1. # Book和Publish 一对多的关系
    2. # Book和Author 多对多的关系
    3. # Author和AuthorDetail 一对一的关系
    4. class Book(models.Model):
    5. title = models.CharField(max_length=32)
    6. price = models.DecimalField(max_digits=8,decimal_places=2)
    7. publish_date = models.DateField(auto_now_add=True)
    8. publish = models.ForeignKey(to='Publish') # 一对多外键
    9. authors = models.ManyToManyField(to='Author') # 多对多外键
    10. class Publish(models.Model):
    11. name = models.CharField(max_length=32)
    12. addr = models.CharField(max_length=64)
    13. email = models.EmailField() # varchar(254) 该字段类型不是类models看的 而是给后面学习到的校验组件看的
    14. class Author(models.Model):
    15. name = models.CharField(max_length=32)
    16. age = models.IntegerField()
    17. author_detail = models.OneToOneField(to='AuthorDetail') # 一对一外外键
    18. class AuthorDetail(models.Model):
    19. phone = models.BigIntegerField()
    20. addr = models.CharField(max_length=64)

    一对多外键增删改查

    1. # 外键的增
    2. # 方法1 直接写实际字段
    3. # models.Book.objects.create(title='论语',price=899.23,publish_id=1)
    4. # models.Book.objects.create(title='聊斋',price=444.23,publish_id=2)
    5. # models.Book.objects.create(title='老子',price=333.66,publish_id=1)
    6. # 方法2 虚拟字段 对象
    7. # publish_obj = models.Publish.objects.filter(pk=2).first()
    8. # # print(publish_obj) # Publish object 拿到出版社主键值为2的对象
    9. # models.Book.objects.create(title='红螺母',price=299.87,publish=publish_obj)
    10. # 删
    11. # models.Book.objects.filter(pk=4).delete()
    12. # 修改
    13. # 直接修改
    14. # models.Book.objects.filter(pk=1).update(publish_id=2)
    15. # 虚拟字段对象修改
    16. publish_id = models.Publish.objects.filter(pk=1).first()
    17. models.Book.objects.filter(pk=1).update(publish=publish_id)

    多对多外键的增删改查

    1. # 多对多表(第三方表)
    2. # 关系绑定
    3. # 方法1 直接给定绑定编号
    4. book_obj = models.Book.objects.filter(pk=2).first() # 主键值为1的对象
    5. # print(book_obj.authors) # 进入第三个虚拟表中
    6. # book_obj.authors.add(1)
    7. # book_obj.authors.add(2,3) # 给主键为1的Book对象绑定两个作者
    8. # 方法2 虚拟字段 绑定对象
    9. author_obj = models.Author.objects.filter(pk=1).first()
    10. book_obj.authors.add(author_obj)
    11. """
    12. add给第三张关系表添加数据
    13. 括号内既可以传数字也可以传对象 并且都支持多个
    14. """
    15. # 删
    16. # book_obj.authors.remove(2)
    17. # book_obj.authors.remove(1,3)
    18. # author_obj = models.Author.objects.filter(pk=2).first()
    19. # author_obj1 = models.Author.objects.filter(pk=3).first()
    20. # book_obj.authors.remove(author_obj,author_obj1)
    21. """
    22. remove
    23. 括号内既可以传数字也可以传对象 并且都支持多个
    24. """
    25. # 修改
    26. # book_obj.authors.set([1,2]) # 括号内必须给一个可迭代对象
    27. # book_obj.authors.set([3]) # 括号内必须给一个可迭代对象
    28. # author_obj = models.Author.objects.filter(pk=2).first()
    29. # author_obj1 = models.Author.objects.filter(pk=3).first()
    30. # book_obj.authors.set([author_obj,author_obj1]) # 括号内必须给一个可迭代对象
    31. """
    32. set
    33. 括号内必须传一个可迭代对象,该对象内既可以数字也可以对象 并且都支持多个
    34. """
    35. # 清空
    36. # 在第三张关系表中清空某个书籍与作者的绑定关系
    37. book_obj.authors.clear()
    38. """
    39. clear
    40. 括号内不要加任何参数
    41. """

    正反向的概念

    1. # 正向
    2. # 反向
    3. 外键的字段在我手上 我查你就是正向
    4. 外键的字段如果不在手上 我查你就是反向
    5. book 外键的字段在书那(正向)》》publish
    6. publish 外键的字段在书那(反向)》》book
    7. 一和一和多对多的正反向判断也是如此
    8. 正向查询按字段
    9. 反向查询按表明小写 ——set

    多表查询

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

    1. # 1.查询书籍主键为1的出版社
    2. # book_obj = models.Book.objects.filter(pk=1).first()
    3. # # 书查出版社 正向
    4. # res = book_obj.publish
    5. # print(res)
    6. # print(res.name)
    7. # print(res.addr)
    8. # 2.查询书籍主键为2的作者
    9. # book_obj = models.Book.objects.filter(pk=2).first()
    10. # # 书查作者 正向
    11. # # res = book_obj.authors # app01.Author.None
    12. # res = book_obj.authors.all() # , ]>
    13. #
    14. # print(res)
    15. # 3.查询作者jason的电话号码
    16. # author_obj = models.Author.objects.filter(name='jason').first()
    17. # res = author_obj.author_detail
    18. # print(res)
    19. # print(res.phone)
    20. # print(res.addr)
    21. """
    22. 在书写orm语句的时候跟写sql语句一样的
    23. 不要企图一次性将orm语句写完 如果比较复杂 就写一点看一点
    24. 正向什么时候需要加.all()
    25. 当你的结果可能有多个的时候就需要加.all()
    26. 如果是一个则直接拿到数据对象
    27. book_obj.publish
    28. book_obj.authors.all()
    29. author_obj.author_detail
    30. """
    31. # 4.查询出版社是东方出版社出版的书
    32. # publish_obj = models.Publish.objects.filter(name='东方出版社').first()
    33. # 出版社查书 反向
    34. # res = publish_obj.book_set # app01.Book.None
    35. # res = publish_obj.book_set.all()
    36. # print(res)
    37. # 5.查询作者是jason写过的书
    38. # author_obj = models.Author.objects.filter(name='jason').first()
    39. # 作者查书 反向
    40. # res = author_obj.book_set # app01.Book.None
    41. # res = author_obj.book_set.all()
    42. # print(res)
    43. # 6.查询手机号是110的作者姓名
    44. # author_detail_obj = models.AuthorDetail.objects.filter(phone=110).first()
    45. # res = author_detail_obj.author
    46. # print(res.name)
    47. """
    48. 基于对象
    49. 反向查询的时候
    50. 当你的查询结果可以有多个的时候 就必须加_set.all()
    51. 当你的结果只有一个的时候 不需要加_set.all()
    52. 自己总结出 自己方便记忆的即可 每个人都可以不一样
    53. """

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

    1. # 基于双下划线的跨表查询
    2. # 1.查询jason的手机号和作者姓名
    3. # res = models.Author.objects.filter(name='jason').values('author_detail__phone','name')
    4. # print(res)
    5. # 反向
    6. # res = models.AuthorDetail.objects.filter(author__name='jason') # 拿作者姓名是jason的作者详情
    7. # res = models.AuthorDetail.objects.filter(author__name='jason').values('phone','author__name')
    8. # print(res)
    9. # 2.查询书籍主键为1的出版社名称和书的名称
    10. # res = models.Book.objects.filter(pk=1).values('title','publish__name')
    11. # print(res)
    12. # 反向
    13. # res = models.Publish.objects.filter(book__id=1).values('name','book__title')
    14. # print(res)
    15. # 3.查询书籍主键为1的作者姓名
    16. # res = models.Book.objects.filter(pk=1).values('authors__name')
    17. # print(res)
    18. # 反向
    19. # res = models.Author.objects.filter(book__id=1).values('name')
    20. # print(res)
    21. # 查询书籍主键是1的作者的手机号
    22. # book author authordetail
    23. # res = models.Book.objects.filter(pk=1).values('authors__author_detail__phone')
    24. # print(res)
    25. """
    26. 你只要掌握了正反向的概念
    27. 以及双下划线
    28. 那么你就可以无限制的跨表
    29. """

  • 相关阅读:
    【Linux】-文件操作(重定向、缓冲区以及Linux下一切皆文件的详解)
    Java多线程并发编程核心知识
    Docker 部署 Bitwarden RS 服务
    基于SSH开发高校选课系统的设计与实现+论文 大作业源码 毕业设计
    音频基础 DAI:Digital Audio Interfaces
    Python网页请求超时如何解决
    MQTT 保留消息是什么?如何使用?
    mapper-reducer编程搭建
    Java学习第十九节之static关键字详解
    目标与学习方向
  • 原文地址:https://blog.csdn.net/m0_59882269/article/details/126022795