zoukankan      html  css  js  c++  java
  • Django框架-模型层3/数据传输/Ajax

    一、orm查询优化

    能少走数据库就少走数据库。

    1.only与defer

    only:取对象,对象中只包含主键和only括号里的属性。

    only括号内放字段,查询结果是一个列表套一个个的数据对象。

    这些数据对象通过点的方式取括号内的字段属性不会再查询数据库,直接就是对象获取属性。只需要查一次数据库就可以全取出。

    不过only也可以点击括号内没有的字段,但是每点击一次就会重新走一次数据库查询,效率极低。

    res = models.Book.objects.only('title')
    for i in res:
        print(i.title)  # 走一次
    
    for i in res:
    	print(i.price)  # 走11次,有几个对象走几次
    

    defer:与only相反,排除括号内的字段。

    defer与only是互为反操作。

    defer括号内放什么字段,查询出来的对象就没有该字段属性。

    如果你要点击括号内的对象,每点击一次就要重新走一次数据。

    而你如果点击了非括号内的字段,就不会走数据库,仅仅是对象点属性取值的操作。

    res = models.Book.objects.defer('title')
    # print(res)
    for i in res:
        print(i.title)  # 有几个对象走几次
    
    for i in res:
        print(i.price)  # 走一次
    

    select_related:用来优化查询外键的操作。

    select_related括号内只能放外键字段,并且外键字段的类型只能是一对多 或者一对一,不能是多对多。多对多会报错。

    内部是join自动连表操作,会将括号内外键字段所关联的表与当前表自动拼接成一张表。

    然后将表中的数据一个个查询出来封装成一个个的对象。

    这样做的好处就在于跨表也不需要重复的走数据库了,减轻数据库的压力 。

    select_related括号内可以放多个外键字段(不能是多对多),逗号隔开,会将多个外键字段关联的表与当前表通过sql语句的join方法全部拼成一张大表。

    耗时:数据库层面需要先连表,耗时耗在连表需要的时间。

    res = models.Book.objects.select_related('publisher')
    for i in res:
        print(i.title) 
        print(i.publisher)
    

    prefatch_related:prefetch_related内部是子查询。

    会自动帮你按步骤查询多张表 ,然后将查询的结果封装到对象中。

    给用户的感觉好像还是连表操作。实际内部方法不一样。

    括号内支持传多个外键字段,并且没有类型限制。

    特点:每放一个外键字段,就会多走一条sql语句,多查询一张表。

    耗时:查询的次数长,耗时耗在查询次数上。

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

    两者之间的优缺点:

    需要结合实际情况,看表的大小。

    在两张表都特别大的情况下,连表操作可能耗时更多。

    二、模型层choices参数

    choices参数是模型层中字段的参数,choices属性的值需要为一个提前定义的对应关系容器。

    容器内写数字integerfield(也可以是字符charfield)与状态的对应关系,以元组的形式存在一个大元组里。

    # models
    class User(models.Model):
        sex_choices = (
            (1,'男'),
            (2,'女'),
            (3,'不愿透露'),
        )
        sex = models.IntegerField(choices=sex_choices)
        # 该字段存数字
        # 可以存提前定义好的关系中的数字,也可以存不在关系中的数字
        # 但是取得时候,也可以正常取,但取的是数字
        
    # test
    # 字段中存choices字段类型时,如果想要取出数字对应的值需要用‘get_字段名_display()’方法来获取
    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())  # 没有对应关系,获取到的还是数字本身
    

    三、MTV与MVC模型

    1.MVC

    MVC(Model View Controller 模型-视图-控制器)

    是一种Web架构的模式。特点:把业务逻辑、模型数据、用户界面分离开来,让开发者将数据与表现解耦。

    Model: 代表数据存取层,

    View: 代表的是系统中选择显示什么和怎么显示的部分,

    Controller: 指的是系统中根据用户输入并视需要访问模型,以决定使用哪个视图的那部分。

    2.MTV

    Django框架就是MTV结构的。其实本质还是MVC。

    MTV(Model Templates View 模型-模板-视图):

    1.Models:数据存取层。

    该层处理与数据相关的所有事务: 如何存取、如何验证有效,是一个抽象层,用来构建和操作你的web应用中的数据,模型是你的数据的唯一的、权威的信息源。它包含你所储存数据的必要字段和行为。通常,每个模型对应数据库中唯一的一张表。

    2.模板(templates):即表现层。

    该层处理与表现相关的决定: 如何在页面或其他类型文档中进行显示。模板层提供了设计友好的语法来展示信息给用户。使用模板方法可以动态地生成HTML。模板包含所需HTML 输出的静态部分,以及一些特殊的语法,描述如何将动态内容插入。

    3.视图(views):业务逻辑层。

    该层包含存取模型及调取恰当模板的相关逻辑。用于封装负责处理用户请求及返回响应的逻辑。视图可以看作是前端与数据库的中间人,他会将前端想要的数据从数据库中读出来给前端。他也会将用户要想保存的数据写到数据库。

    3.区别

    MVC中的View的目的是「呈现哪一个数据」,而MTV的View的目的是「数据如何呈现」。

    也就是把MVC中的View分成了视图(展现哪些数据)和模板(如何展现)2个部分,而Contorller这个要素由框架自己来实现了,我们需要做的就是把(带正则表达式的)URL对应到视图就可以了,通过这样的URL配置,系统将一个请求发送到一个合适的视图。

    四、Ajax简介

    AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(XML也是一门标记语言,当然,传输的数据不只是XML)。

    AJAX 不是新的编程语言,而是一种使用现有标准的新方法。

    AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)

    AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。

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

    在前端页面中,Ajax句式非常简单,用jQuery可以很方便的实现:

    // 使用jQuery之前先导入jQuery
    // ajax基本语法结构
    $.ajax({
    	url:'', // 数据提交的后端地址,不写就是往当前页面提交,也可以写后缀,也可以写全称,跟actions一样
    	type:'post',  // 提交方式,不写默认是get请求
    	data:"{i1:$('#d1'),i2:$('#d2')}",  // 提交的数据
    	success:function(backdata){ // 形参backdata就是异步提交之后后端返回结果
    		$('#d3').val(backdata)  // 这里是回调机制需要做的事情
    	}
    })
    

    一旦使用了ajax,三板斧都不会再作用域页面,而是和回调函数做交互。

    五、前后端传输数据编码格式

    前后端交互时,不同数据的编码格式是不一样的。

    比如说你用form表单提交数据的时候,传普通的input框的文本和file文件时,后端可以用request.POST/request.FILES 接收文本和文件。

    那么后端为什么可以识别你传的是文本还是文件呢?

    就是因为你传输不同数据时所使用的编码格式不一样。

    1. 不同的编码格式

    目前,我们需掌握的编码格式有三种:

    1. urlencoded (默认,文本)
    2. form-data (文件)
    3. application/json (json格式的数据)

    2. 前端朝后端发送数据的请求方式

    1. a标签href参数:get请求
    2. form表单:get/post
    3. ajax:get/post

    2.1 form表单发送数据编码格式

    django后端只要你的数据满足urlencoded格式:username=tbw&password=123就会自动帮你解析到request.POST中。

    如果你是一个文件对象django后端也会自动识别帮你放到request.FILES中。

    form表单无法发送json格式的数据。

    1. 默认格式

      Content-Type: application/x-www-form-urlencoded(谷歌浏览器可以看)

      form表单发送数据默认编码格式为:urlencoded。

      此格式的形式为:username=tbw&password=123

      django后端针对urlencoded数据 会自动解析并且帮你封装到request.POST中。

    2. 文件

      Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryhjKCHQHDmcE62iMQ

      form表单发送文件数据的编码格式为:form-data

      此格式的形式:你在浏览器上是无法查看到

    3. json

      form表单无法发送json格式的数据。你只能借助于ajax。

    2.2 ajax发送数据的编码格式

    ajax能够发送:
    1.urlencoded
    2.form-data
    3.application/json
    三种格式的数据。

    1. 默认格式

      编码格式为:urlencoded。

      也就意味着后端django也是将数据解析到request.POST中。

    2. ajax发送文件

      编码格式为:form-data。

      需要借助于内置对象:new FormData()

      该对象既可以携带文件数据,也支持普通的键值对。

       $('#d1').click(function () {
           // 先生成一个内置对象
           var MyFormData = new FormData();
           // 1. 先添加普通的键值
           MyFormData.append('username','tbw');  // 添加了一组普通的键值对
           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) {
               }
           })
       })
      
    3. ajax发送json格式数据

      ajax发送json格式数据的方式:

      $('#d1').click(function () {
      	$.ajax({
      		url:'',
      		type:'post',
      		contentType:'application/json',
      		data:JSON.stringify({'username':'jason','password':'123'}),
      		success:function (data) {
      		alert(123)
      	}
      })
      

      Django后端接收json格式数据的方法:

      # django后端针对json格式的数据不会做任何处理,
      # 数据怎么来的,只会原封不动的放到request.body中,也就是接收到的是二级制数据
      json_bytes = request.body
      # 解码
      # json_str = str(json_bytes,encoding='utf-8')
      json_str = json_bytes.decode('utf8')
      # 反序列化
      json_dic = json.loads(json_str)
      # json_dic = json.loads(json_bytes)  # 自动帮你解码加反序列化
      print(json_dic,type(json_dic))
      

    六、序列化(drf会用到)

    目的:将数据整合成一个大字典形式,方便数据的交互。

    使用serializers模块完成序列化。

    from django.core import serializers
    def zzz(request):
    	user_queryset = models.User.objects.all()
    	res = serializers.serialize('json',user_queryset)
    	return HttpResponse(res)
    
  • 相关阅读:
    GridView简单应用
    利用Field获取图片
    css的三种书写方式
    css选择器概述
    关于Object数组强转成Integer数组的问题:Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;
    easyUI按钮图表对照大全
    jquery绑定点击事件的三种写法
    css中关于table的相关设置
    Leetcode 287. 寻找重复数
    LeetCode 278. 第一个错误的版本
  • 原文地址:https://www.cnblogs.com/bowendown/p/11967994.html
Copyright © 2011-2022 走看看