专栏首页python小白的成长计划Django数据库查询优化与AJAX

Django数据库查询优化与AJAX

数据库设计三大范式

第一范式(1NF):列不可再分(原子性)

每一列属性都是不可再分的,两列的属性相近或相似或一样,应尽量合并属性一样的列,确保不产生冗余数据。

第二范式(2NF):属性完全依赖路主键(唯一性)

第二范式是在第一范式的基础上建立起来的,也就是第二范式要求数据库表中的每个实例或行必须可以被唯一的区分,也就是一张表至少有一个主键来区分每一条记录。

第三范式(3NF):属性不依赖于其他非主键属性,属性直接依赖于主键(冗余性)

不同的属性之间不能有传递关系,也就是每一个属性的数据不能相互影响。

orm相关的数据库查询优化

惰性查询

惰性查询指当我们只查数据库而不是用这些数据时,Django不会执行查询数据库的代码,目的是减少不必要的数据库操作,降低数据库的压力。

如:

    res = models.Book.objects.all()#只有当我们使用res时才会执行数据库查询的操作

all、only与defer

all

拿到自己的所有的属性,但是没有与其他表建立外键的属性。

only

only括号内放字段,查询结果是一个列表套一个个数据对象,这些数据对象点括号内的字段属性,不会再查数据库,直接就是对象获取属性;也支持点其他属性,但是其他属性会每拿一条数据就走一次数据库。

res = models.Book.objects.only('name')#查询一次
    print(res)
    for i in res:
        print(i.name)
        
res = models.Book.objects.only('name')#查询多次
    print(res)
    for i in res:
        print(i.price)       

defer

defer与only是互为反操作,点括号内的属性会每拿一条数据就走一次数据库,点其他的属性反而只走一次数据库。

res = models.Book.objects.defer('name')#查询多次
    print(res)
    for i in res:
        print(i.name)
        
res = models.Book.objects.defer('name')#查询一次
    print(res)
    for i in res:
        print(i.price) 

括号内只能放一对一、一对多的外键字段,特点:内部自动连表操作,会将括号内外键字段所关联的表与当前表自动拼接成一张表,然后将表中的数据一个一个查询出来封装成一个一个的对象。

这样做的好处:跨表查询也不需要重复走数据库,减轻数据库压力。select_related()括号内放多个外键字段,逗号隔开,会将多个外键字段关联的表与当前表拼成一张大表。

耗时:数据库层面连表操作,当数据库特别大时可能连表的时间会长一点,用prefetch_related可能会好一点,但如果表比较小两者基本没太大差别。

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

prefetch_related内部是子查询(当一个查询是另一个查询的条件时,称之为子查询。),特点:按步骤查询多张表,然后将查询结果封装到对象中,给用户的感觉好像还是连表操作,括号内支持传多个外键字段,每放一个外键字段就会多走一条SQL语句,多查一张表。

使用:主要用于多对多字段和一对多字段

耗时:查询的次数上

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

MTV与MVC模型

MTV(models templates views)

models templates views:模型层、模板层、视图层

Django自称是MTV框架,其实本质还是MCV

MCV(models views controllar)

models views controllar:模型层、视图层、控制层

controllar指url(路由匹配)

choices参数

choices参数指一个字段只有几个情况可以选择,比如性别字段只有两个情况,类似的还有在职状态、学历、婚否等。

我们可以用0、1等数字代表男女等字段可能的情况,将数字存入表中(可以是数字也可以是字符串,通常用-1表示数据短缺或者数据丢失),取出的时候如果存储的数字在提前定义好的关系中会,则会取出对应关系的字符串,如果没有对应关系,取出的还是数字。

choices字段类型在获取值的时候统一句式:get_字段名_display()

class User(models.Model):
    username = models.CharField(max_length=64)
    password = models.IntegerField()
    gender_choices = (
        (1,'男'),
        (2,'女'),
        (3,'其他'),
    )
    gender = models.IntegerField(choices=gender_choices)

Ajax(重要)

AJAX简介

AJAX(Asynchronous Javascript And XML)“异步的Javascript和XML”,即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)。

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

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

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

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

AJAX的应用场景

搜索引擎根据用户输入的关键字,自动提示检索关键字,网站注册时候的实时用户名的查重,特点:

  • 不刷新页面的前后端数据交互
  • 异步操作,当请求发出后,浏览器还可以进行其他操作

AJAX前的知识储备

XML简单介绍

XML是一门标记语言,它的应用场景有:

1.写配置文件

2.写前端页面如odoo框架(公司内部管理软件开发框架,内部功能的实现全部依赖于python2)中的erp。

JSON简介

  • JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation)
  • JSON 是轻量级的文本数据交换格式
  • JSON 独立于语言 *
  • JSON 具有自我描述性,更易理解

* JSON 使用 JavaScript 语法来描述数据对象,但是 JSON 仍然独立于语言和平台。JSON 解析器和 JSON 库支持许多不同的编程语言。

前端JAON对象与Python json模块的对应关系:

stringfy和parse方法

JavaScript中关于JSON对象和字符串转换的两个方法:

JSON.parse(): 用于将一个 JSON 字符串转换为 JavaScript 对象(json只认双引的字符串格式)

JSON.parse('{"name":"ylpb"}');
JSON.parse('{name:"ylpb"}') ;   // 错误
JSON.parse('[18,undefined]') ;   // 错误

JSON.stringify(): 用于将 JavaScript 值转换为 JSON 字符串。

JSON.stringify({"name":"Tonny"})

经过json序列化的数据以字符串的数据类型存储的,这点是必须要清楚的,如

b = json.dumps({'password': 123})
print(type(b))
#<class 'str'>
print(b)
#{"password": 123}
#这点容易造成误解因为我们看到的好像并不是一个字符串

ajax基本语法结构:

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

前后端传输数据的编码格式

前后端进行数据交互的时候,针对不同的数据后端会进行不同的处理,Django中的request.POST、request.GET、request.FILES

前端向后端发送数据的时候需要指定数据编码格式,目前我们需要了解的有三种:urlencoded、formdata、json

form表单向后端发送数据的编码格式有两种,第一种是我们没有配置enctype时,它默认的编码格式是urlencoded,当我们发送文件时需要将enctype设置成 multipart/form-data,这样form表单发送文件的时候就采用formdata的格式进行编码。但是问题来了前端如何向后端发生json格式的数据呢?这个时候只能借助于AJAX才能完成json格式数据的发送,AJAX可以发送上述的三种编码格式的数据

AJAX如何传输json数据

前端代码:

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

说明:

1.需要设置contentType:'application/json'。

2.对JSON数据进行序列化。

3.Django后端针对json格式的数据不会做任何的处理,只是将数据原封不动的放在了request.body中,我们需要手动对其进行反序列化处理。

AJAX发送文件

<form action="">
    username:<input type="text" name="username">
password:<input type="text" name="password">
myfile:<input type="file" name="myfile" id="d2">
</form>

<button id="d1">点我发送文件数据</button>
<script> 

// 传文件
    $('#d1').click(function () {
        // 先生成一个内置对象
        var MyFormData = new FormData();
        // 1. 先添加普通的键值
        MyFormData.append('username','ylpb');  // 添加了一组普通的简直对,append后面第一个参数是键,第二个参数是值
        MyFormData.append('password','123');
        MyFormData.append('hobby',['read','run']);
        // 2. 添加文件数据MyFormData.append(文件名,文件数据)
        MyFormData.append('myfile',$('#d2')[0].files[0]);  // 获取input框中文件对象的方法:$('#d2')[0].files[0] 方法介绍:找到id为d2(input框的id)的jQuery对象$('#d2'),然后索引0拿到标签对象即$('#d2')[0],然后使用files方法获取文件数据
        $.ajax({
            url:'',
            type:'post',
            data:MyFormData,

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

            success:function (data) {

            }

        })
    })
</script>

Django后端可以自动识别MyFormData(我们自己生成的内置对象)中的普通键值和文件,普通键值放在request.POST里面,文件放在request.FILES里面。

序列化

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

Django内置的serializers模块

前端想拿到通过orm查到的一个个对象,(数据库里的一条条记录),后端想把直接实例化出来的对象发送给前端,这时候就需要用到Django给我们提供的序列法方式(其实就是列表套字典的形式将数据发送出去)。

使用方法:

def ser(request):
    #拿到用户表里面的所有的用户对象
    user_list=models.User.objects.all()
    #导入内置序列化模块
    from django.core import serializers
    #调用该模块下的方法,第一个参数是你想以什么样的方式序列化你的数据
    ret=serializers.serialize('json',user_list)
    return HttpResponse(ret)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 数据库迁移常见的四种方法

    数据的迁移就像搬家,基本每个用过手机的人都做过数据迁移,将旧智能手机中的电话号码、照片、微信聊天记录导入到另一台新的智能手机。因此数据迁移并不神秘。在上云的过程...

    希望的田野
  • MySQL事务与乐观锁

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

  • 注意Spring事务这一点,避免出现大事务

    本篇文章主要分享压测的(高并发)时候发现的一些问题。之前的两篇文章已经讲述了在高并发的情况下,消息队列和数据库连接池的一些总结和优化,有兴趣的可以在我的公众号中...

    用户5397975
  • HBase RowKey 设计

    HBase中 RowKey 用来唯一标识一行记录。在 HBase 中检索数据有以下三种方式:

    smartsi
  • Mysql索引分类

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

    chenchenchen
  • HBase Schema 设计

    HBase 与传统关系数据库(例如MySQL,PostgreSQL,Oracle等)在架构的设计以及为应用程序提供的功能方面有很大的不同。HBase 权衡了其中...

    smartsi
  • OLAP vs OLTP

    OLTP 是 Online Transaction Processing 的简称,是一个联机事务处理系统,主要目标是数据处理而不是数据分析。OLTP 系统的主要...

    smartsi
  • MySQL用得好好的,为啥非要转ES?

    京东到家订单中心系统业务中,无论是外部商家的订单生产,或是内部上下游系统的依赖,订单查询的调用量都非常大,造成了订单数据读多写少的情况。

    江南一点雨
  • SQL查询并不总是以SELECT开始

    很多 SQL 查询确实以 SELECT 开始(本文仅涉及 SELECT 查询,而不涉及 INSERT 或其他内容)。不过,我在网上搜索 ‘是否可以对窗口函数返回...

    smartsi
  • Linux查看实时带宽流量情况以及查看端口信息

    Linux中查看网卡流量工具有iptraf、iftop以及nethogs等,iftop可以用来监控网卡的实时流量(可以指定网段)、反向解析IP、显示端口信息等。

    十四君

扫码关注云+社区

领取腾讯云代金券