11.29 总结

Posted lidandanaa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了11.29 总结相关的知识,希望对你有一定的参考价值。

ORM查询优化

only 与defer

'''
    数据库查询优化
    only 与 defer
    '''
    res=models.Book.objects.all()
    print(res)
    for i in res:

        print(i.price)
        print(i.title)
    res1=models.Book.objects.only('title')
    print(res1)
    for i in res1:

        print(i.price)
        print(i.title)
    '''
    only 括号内放字段 查询结果是一个列表套一个个数据对象
    这些数据对象点括号内的字段属性不会再查数据库
    也支持点击括号内没有的字段 但是每点击一次就会重新走一次数据库查询 效率极低
    '''
    
    res=models.Book.objects.defer('title')
    # print(res)
    for i in res:
        # print(i.title)
        print(i.price)
        
    '''
    defer 与only互为反操作
    defer括号内放什么字段 查询出来的对象就没有该字段属性
    需要全表搜索找到该属性
    如果点击了括号内没有的字段 就不会全表查询 仅仅是对象属性的操作
    '''
'''
    select_related与prefetch_related
    select_related括号内只能放外键字段 并且外键字段的类型只能是一对多 或者 一对一 不能是多对多
    内部是自动连表操作 会将括号内外键字段所关联的表 与当前表自动拼接成一张表
    然后将表中的数据一个个查询出来封装成一个个对象
    这样做的好处就在于跨表也不需要重复的走数据库了 减轻数据库压力
    select_related 括号内可以放多个外键字段 逗号隔开 会将多个外键字段关联的表与当前表全部拼成一张大表
    耗时:数据库层面需要先连表
    '''

    res=models.Book.objects.select_related('publish')
    print(res)
    for i in res:
        print(i.title)
        print(i.publish)
        
    '''
    prefetch_related 内部是子查询
    会自动帮你按照步骤查询多张表 然后将查询的结果封装到对象中
    给用户的感觉好像还是连表操作
    括号内支持传多个外键字段 并且没有类型限制
    特点:每放一个外键字段 就会多走一条SQL语句 多查询一张表
    
    耗时:查询的次数长
    '''

    '''
    两者之间的优缺点 
    结合实际情况 表的大小
    两张表都特别大的情况下 连表操作可以耗时更多
    '''

    res=models.Book.objects.prefetch_related('publish','authors')
    print(res)
    for i in res:
        print(i.title)
        print(i.publish)

MTV 与MVC模型

  • django自称为是MTV框架 本质其实还是MVC
  • MTV
    • M:models
    • T:templates
    • V:views
  • MVC
    • M:models
    • V:views
    • C:controllar 路由匹配

choices参数

#models.py
from django.db import models
#
# # Create your models here.
class User(models.Model):
    username = models.CharField(max_length=64)
    password = models.IntegerField()
    gender_choices = (
        (1,'男'), #第一个参数不一定必须是数字,也可以是字符串,只要你事先定义好对应关系,利用固定语法对象.get_字段名_display(),就可以获取对应的注释
        (2,'女'),
        (3,'其他'),
    )
    gender = models.IntegerField(choices=gender_choices)
#     # 该字段存数字
#     """
#     1.如果存储的数字在我们提前定义好的关系中会怎么样
#     2.如果存储的数字不在关系中又会怎么样
#         能够正常存储
#         也能够正常获取(数字)
#tests.py
import os


if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day55.settings")
    import django
    django.setup()
    from app01 import models

    user_obj = models.User.objects.get(pk=1)
    user_obj1 = models.User.objects.get(pk=4)
    # print(user_obj.gender)
    # print(user_obj1.gender)
    # print(user_obj.get_gender_display())
    print(user_obj1.get_gender_display())  # 没有对应关系 获取到的还是数字本身
    """
    只要是choices字段类型 在获取值的时候 统一句式
    get_字段名_display()  能拿到对应关系所对应的注释
    """

Ajax简介

  • XML
    • 它也是一门标记语言 该语法应用场景
      • 写配置文件
      • 可以写前端页面(odoo框架 erp)
  • AJax最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)
#例子:页面上有三个input框
    前两个是数字  最后一个展示两者的和
    要求是求和的时候页面不刷新
#views.py
def xxx(request):
    # print(request.is_ajax())  # 判断当前请求是否是ajax请求
    # print(request.POST)  # ajax发送的post请求 普通的键值对也在request.POST中获取
    if request.is_ajax():
        i1 = request.POST.get('i1')
        i2 = request.POST.get('i2')
        # 不做校验
        res = int(i1) + int(i2)
        return HttpResponse(res)  # 给异步回调函数 success
        # return render(request,'xxx.html')  #  页面给了data,不再作用于浏览器
        # return redirect('https://www.baidu.com')  # 不会再重定向
    return render(request,'xxx.html')
#html页
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<input type="text" id="d1">  + <input type="text" id="d2"> = <input type="text" id="d3">
<button id="d4">点我发送请求</button>

<script>
    $('#d4').on('click',function () {  //button的点击事件
        {#alert(123)#}
        // 获取前面两个框的内容 将数据发送给后端

        // 开启ajax语法局势
        $.ajax({
            url:'',  // 数据提交的后端地址  不写就是往当前页面提交  也可以写后缀 也可以写全称  跟actions一样
            type:'post',  // 提交方式  默认是get请求
            data:{'i1':$('#d1').val(),'i2':$('#d2').val()},  // 提交的数据
            success:function (data) {  // 形参data就是异步提交之后后端返回结果
                {#$('#d3').val(data)  // 回调机制需要做的事情#}
                alert(data)
            }
        })
    })
  • 一旦使用了ajex 三板斧不再跟浏览器窗口交互,而是和返回的data交互,把数据给data,也就是内部自己在交互

前后端传输数据编码格式

  • 前后端交互针对不同数据 会使用不同的编码格式
    • request.POST
    • request.FILES
    • urlencoded
    • formdata
    • application/json
  • form表单发送数据的编码格式urlencoded
    • Content-Type: application/x-www-form-urlencoded
    • form表单默认的编码方式是urlencoded
    • urlencooded 所对应的数据格式--username=jason&password=123
    • django后端只要你的数据满足urlencoded格式 会自动解析并帮你封装到request.POST中
#views.py
def xxx(request):
    # print(request.is_ajax())  # 判断当前请求是否是ajax请求
    # print(request.POST)  # ajax发送的post请求 普通的键值对也在request.POST中获取
    if request.is_ajax():
        i1 = request.POST.get('i1')
        i2 = request.POST.get('i2')
        # 不做校验
        res = int(i1) + int(i2)
        return HttpResponse(res)  # 给异步回调函数 success
        # return render(request,'xxx.html')  #  页面给了data,不再作用于浏览器
        # return redirect('https://www.baidu.com')  # 不会再重定向
    return render(request,'xxx.html')

#xxx.html
<body>
<input type="text" id="d1">  + <input type="text" id="d2"> = <input type="text" id="d3">
<button id="d4">点我发送请求</button>

<script>
    $('#d4').on('click',function () {  //button的点击事件
        {#alert(123)#}
        // 获取前面两个框的内容 将数据发送给后端

        // 开启ajax语法局势
        $.ajax({
            url:'',  // 数据提交的后端地址  不写就是往当前页面提交  也可以写后缀 也可以写全称  跟actions一样
            type:'post',  // 提交方式  默认是get请求
            data:{'i1':$('#d1').val(),'i2':$('#d2').val()},  // 提交的数据
            success:function (data) {  // 形参data就是异步提交之后后端返回结果
                $('#d3').val(data)  // 回调机制需要做的事情
                {#alert(data)#}
            }
        })
    })
  • form表单发送文件 编码格式form-data;
    • Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryhjKCHQHDmcE62iMQ
    • 针对formdata格式的数据 在浏览器上是无法查看到的
    • 如果你是一个文件对象django后端也会自动识别帮你放到request.FILES中
#yyy.html
<form action="" method="post" enctype="multipart/form-data">
    username:<input type="text" name="username">
    password:<input type="text" name="password">
    myfile: <input type="file" name="myfile">
    <input type="submit">
</form>
  • form表单无法发送json格式的数据 要想发只能借助与Ajex

    • Ajex发送数据的编码格式Content-Type: application/x-www-form-urlencoded; charset=UTF-8
    • ajex能够发送urlencoded、formdat、application/json三种格式
    • ajex默认的编码格式也是urlencoded 也就意味着后端django也是将数据解析到request.POST
  • 在涉及到数据交互的时候 一定要做到数据的格式和编码格式一致

Ajax如何传输json格式数据

Content-Type: application/json
    {"username":"jason","password":"123"}
  • django后端针对json格式的数据 不会做任何处理 数据怎么来的 只会原封不动的放到request.body中,需要自己手动处理
<script>
    // 传json格式的数据
    $('#d1').click(function () {
        $.ajax({
            url: '',
            type: 'post',
            contentType: 'application/json',
            data: JSON.stringify({'username': 'jason', 'password': '123'}),
            success: function (data) {
                alert(123)
            }
        })
    })

Ajax如何传输文件数据

  • 借助于内置对象new
  • 该对象既可以携带文件数据 同样支持普通的键值对
  // 传文件
    $('#d1').click(function () {
        // 先生成一个内置对象
        var MyFormData =  new FormData();
        // 1. 先添加普通的键值
        MyFormData.append('username','jason');  // 添加了一组普通的简直对
        MyFormData.append('password','123');
        MyFormData.append('hobby',['read','run']);
        // 2. 添加文件数据
        MyFormData.append('myfile',$('#d2')[0].files[0]);  // 如何获取input框中文件对象$('#d1')[0].files[0]
        $.ajax({
            url:'',
            type:'post',
            data:MyFormData,

            // 发送文件必须要指定的两个参数
            contentType:false,  // 不适用任何编码  MyFormData对象内部自带编码 django后端能够识别
            processData:false,  // 不要处理数据

            success:function (data) {

            }

        })
    })


</script>

序列化

drf--django restframework 
        from app01 import models
        from django.core import serializers
        # 序列化目的  将数据整合成一个大字典形式 方便数据的交互
        def zzz(request):
            user_queryset = models.User.objects.all()
            # [{username:...,password:...,hobby:...,},{},{},{}]
            # user_list = []
            # for data in user_queryset:
            #     user_list.append(
            #         {'username':data.username,
            #          'password':data.password,
            #          'gender':data.get_gender_display(),
            #
            #          }
            #     )
            user_list = serializers.serialize('json',user_queryset)
            return HttpResponse(user_list)

以上是关于11.29 总结的主要内容,如果未能解决你的问题,请参考以下文章

一阶段总结11.29

11.29 展示总结

11.29个人总结

11.29-12.5博客精彩回顾

11.28 限定某个目录禁止解析php 11.29 限制user_agent 11.30/11.31

11.29