• django----orm查询优化 MTV与MVC模型 choice参数 ajax serializers


    orm查询优化

    onlydefer(推迟)

    djangoorm是惰性查询 目的:减少不必要的数据库操作 降低数据库压力(能少走一次数据库就少走数据库)

    only

    # 案例
    res = models.Book.object.values('title') # 拿到的是列表套字典
    for i in res:
        print(res.title) # 不能够点取值
      
    res = models.Book.object.only('title') # 括号内放字段 :[数据对象,] 
    for i in res:
        print(res.title) # 使用点方法 不会走数据库 直接就是对象获取属性
        print(res.pirce) # 也可以点括号内没有包含的字段 也可以 但是每查询一次就走一次数据库 效率极低 
    

    defer

    # 案例
    res = models.Book.object.defer('title') # 括号内放字段 :[数据对象,] 
    for i in res:
        print(res.title) # 括号内放的字段 查询出来的就没有该字段 如果点了就会走数据库
        print(res.price) # 使用点方法 不会走数据库 直接就是对象获取属性
    

    总结:defer和only互为相反关系

    select_related(有关系的)与prefetch_related(预先载入)

    select_related括号内只能放外键字段并且只能是一对多 或者 一对一 不能是 多对多

    # 案例 
    res = models.Book.object.select_related('publish')
    for i in res:
    	print(res.publish)
     
    # 可以放多个外键字段 会将多个外键字段关联的表与当前表拼成一张大表 用逗号隔开
    

    总结:内部是自动连表操作 会将括号内外键字段所关联的表 与 当前的表自动拼接成一张 然后 将表中的数据一个个查询出来封装成一个个对象

    prefetch_related内部是一个子查询(会自动帮你按步骤查询多张表, 然后将查询的结果封装到对象中, 给用户的感觉还是连表操作)

    # 案例
    res = models.Book.ojbect.prefetch_related('publish', 'author__title')
    for i in res:
        print(i.publish)
    # 特点:每添加一个外键字段就会多走一条sql语句 支持多对多
    

    总结:select_related 耗时: 连表操作

    ​ prefetch_related 耗时: 查询的次数长

    两者之间的优缺点:结合实际情况

    MTV 与 MVC 模型

    ​ 纯理论:django自称为是MTV框架 本质还是MVC

    ​ MTV : models templates views

    ​ MVC : models views controller(路由匹配) 控制器

    ​ Vue : Mvvm

    choice参数

    ​ 例子: 用户表的 性别 在职状态 学历 婚否 这几个字段都是有一个明确范围的

    ​ 我们可以提前给他一个对应关系 按照提前设计好的对应关系取出对应的真正数据

    # 以性别为例
    class User(models.Model):
        username = models.CharField(max_length=255)
        gender_choices = (
        	(1,'男'),
            (2,'女'),
            (3,'其他'),
        ) 
        gender = models.IntegerField(choices=gender_choices) # 该字段存的是数字
        # 验证: 如果存储的数字在我们提前定义好的关系中会怎么样
        1 能够正常存储 2 也能够正常获取 获取的数字 
        # 如果不在会怎么样
    
        (*******) 只要是choice字段类型 在获取值的时候统一句式 get_字段名_display
        res = models.User.object.get(pk=1)
        print(res.get_gender_display())  (******)
        # 如果拿没有对应关系的 获取到的还是数据本身
    

    Ajax

    ​ (异步的JavaScript和xml xml也是一门标记语言 也可以写前端页面 (odoo框架 erp))

    ​ ajax最大的特点 : 不从新加载页面的情况下, 可以与服务器交互数据并更新(不知不觉完成请求和响应)

    ​ 同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;

    异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。
    

    前端代码

     $('#b1').click(function () {
            $.ajax({
                url:'', // 指定url
                type:'POST', // 指定提交方式 默认是get方式
                data:{i1:$('#i1').val(),i2:$('#i2').val()}, // 提交数据
                success:function (data) { // data就是异步提交之后后端返回的结果
                    $('#i3').val(data) // 响应成功后执行的函数
                }
            })
        })
    

    后端代码

    def ajax(request):
        print(request.is_ajax()) # 判断当前请求是否是ajax请求
        print(resqust.POST) # ajax发送的post请求 普通的键值对也是在request.POST中
        return JsonResponse('哈哈哈')
    	return HttpResponse('哈哈') # 会给异步回调函数的data
    	return render(request, 'http.html') # 不会给浏览器 只会给回调函数的data 
    	return redirect('/home/') # 所有的三剑客都不会作用于页面 而是和data交互
    

    前后端传输数据编码格式

    ​ 前后端交互的时候有一个数据编码格式, 针对不同的数据 后端会进行不同的处理

    request.POST request.FILES 我们学过的获取数据方式

    ​ (*****)编码格式 有 三种 1.urlencoded 2. formdata 传的是文件 3. application/json

    能够向后端发送数据的方式
    a 标签的href参数  get请求
    form 表单        get/post
    	请求头中(提前携带一些数据 让后端知道 kv键值对)
        Content-Type: urlencode 默认 
        数据在 form-data 里面 对应的数据格式是 user=xxx&user=xxx
        	django后端针对urlencoded数据 会自动解析并且帮你封装到request.post中
    ajax 提交        get/post
    

    from表单传文件

    ​ 指定type=file 编码格式指定为formdata 针对formdata格式的数据 你在浏览器中是看不到的

    ​ 指定 enctype = formdata 即可拿到post 也可以拿到file 但是不指定 拿到的文件仅仅只是一个文件名字

    ​ 后端获取: request.FILES 拿到文件对象

    form表达无法发送json格式的数据 如果想法只能借助于ajax(****)

    ajax指定编码格式

    传json

    // ajax 默认是 urlencode编码格式
    // ajax 能够发送 上面三种的格式数据
    
    // ajax 传输json格式数据(******)
    $('#d1').click(function(){
        $.ajax({
            url:'',
            type:'post',
            contentType:'', // 不写默认是 urlencoded
            contentType:'application/json' // 指定json格式
            data:JOSN.stringify({'user':'龙哥'}), // 转换json数据
            success:function(data){
                window.console.log('data')
            }
        })
    })
    

    后端获取json

    # 后端如何拿到json格式的数据
    # django后端针对json格式的数据 不会做任何处理 数据怎么来的 只会原封不动的放到request.body中(******) 需要手动处理 是个二进制
    json_bytes = request.body
    json_str = json_bytes.decode('utf-8') or str(json_bytes, encode('utf-8'))
    import json
    json_dic = json.loads(json_str) 
    # 其实json可以直接帮你解码和反序列化 
    

    传文件

    // ajax 传输 文件格式数据(******)
    // 需要借助于一个内置对象 new 该对象既可以携带文件数据 也 支持 普通的键值对
    
    $('#d1').click(function(){
        // 生成一个内置对象
        var MyFormData = new FormData()
        // 1. 先添加普通建值
        MyFormData.append('username','LOGN')
        MyFormData.append('PASSWORD','123')
        // 2. 添加文件数据
        MyFormData.append('myfile',$('#d1')[0].files[0]) // ******
        
        $.ajax({
            url:'',
            type:'post',
            data:MyFormData, // ***** 对象内部自带编码 自动识别
            processData:false, // 指定 process 处理 进程
            contentType:false 指定
            success:function(data){
                window.console.log('data')
            }
        })
    })
    

    后端获取文件

    # 自动放在 
    request.POST and request.FILES 里面
    

    django自带的serializers

    序列化的目的是 将数据整合成一个大字典的形式 方便数据交互

    from app01 import models
    def zzz(request):
        user_queryset = models.User.objects.all()
        user_list = []
        for user_obj in user_queryset:
            user_list.append({
                'username': user_obj.username,
                'password': user_obj.password,
            })
        return HttpResponse(user_list)
    

    def ser(request):
        #拿到用户表里面的所有的用户对象
        user_list=models.User.objects.all()
        #导入内置序列化模块
        from django.core import serializers
        #调用该模块下的方法,第一个参数是你想以什么样的方式序列化你的数据
        ret=serializers.serialize('json',user_list)
        return HttpResponse(ret)
    
  • 相关阅读:
    南阳779
    南阳599
    南阳484
    margin叠加相邻两个元素的上下margin是叠加在一起
    margin
    padding
    css05 字体以及行间距
    mysql相似于oracle的to_char() to_date()方法
    sqlite两表更新update
    SQL查找重复项目
  • 原文地址:https://www.cnblogs.com/lddragon1/p/11958496.html
Copyright © 2020-2023  润新知