orm查询优化 MTV和MVC模型 字段的chioces参数 Ajax
一、ORM查询优化
- 遵循能少走一次数据库就少走一次,即一次查询操作中能少用SQL查询语句就尽量少用。
1. all()
查询
惰性查询 减少不必要的数据库操作 降低数据库的压力
res = models.Book.objects.all()
# 针对这行代码,如果不使用res,则不会执行数据库查询的。
2. only()/defer()方法
(1)only()方法
only()
括号内放字段 查询结果是一个列表套一个个的数据对象,即queryset对象。这些数据对象点括号内的字段不会再查询数据库,直接就是对象获取属性
也支持点括号内没有的字段,但是每点一次就会重新走一次数据库查询,此时查询效率极低。
实例
res = models.Book.objects.only('title')
print(res)
for i in res:
print(i.title) # 只会走最初的那一次,这行不走数据库
print(i.price) # 除了最初查询走的那一次,每到这一行都会再走一次数据库进行查询
(2)defer()方法
defer()
与only()
是互为反操作defer()
括号内放什么字段 查询出来的对象就没有该字段属性如果你要对象点括号内的字段,每点一次就要重新走一次数据
而你如果点击了非括号内的字段,就不会走数据库,仅仅是对象点属性的操作
实例
res = models.Book.objects.defer('title')
print(res)
for i in res:
print(i.title) # 除了最初查询走的那一次,每到这一行都会再走一次数据库进行查询
print(i.price) # 只会走最初的那一次,这行不走数据库
3. select_related()/prefetch_related()
(1)select_related()
select_related原理是联表查询
select_related括号内只能放外键字段 并且外键字段的类型只能是一对多 或者 一对一 不能是多对多
内部是自动联表操作,会将括号内外键字段所关联的表,与当前表自动拼接成一张表
然后将表中的数据一个个查询出来封装成一个个的对象,这样做的好处就在于跨表也不需要重复的走数据库了,减轻数据库的压力
耗时:主要在联表时耗时(数据库层的操作)
实例
res = models.Book.objects.select_related('publish') # publish为外键字段
print(res)
for i in res:
print(i.title) # title为普通字段 , 只是对象点属性获取属性值,不走数据库
print(i.publish) # 只是对象点属性获取属性值,不走数据库
(2)prefetch_related()
prefetch_related原理是子查询
自动帮你按步骤查询多张表,然后将查询的结果封装到对象中,用户的感觉好像还是联表操作
括号内支持传多个外键字段,并且没有类型限制
特点:每放一个外键字段,就会多走一条sql语句,多查询一张表
耗时:查询的次数上的耗时
实例
res = models.Book.objects.prefetch_related('publish','authors') # publish 和 authors都是外键字段, publish是一对多的外键字段,authors是多对多的建立第三张表的虚拟外键字段
print(res)
for i in res:
print(i.title) # 只是对象点属性获取属性值,不走数据库
print(i.publish) # 只是对象点属性获取属性值,不走数据库
(3)select_related()/prefetch_related()
的优缺点
- 没有谁比谁好,结合实际情况,使用不同方法。
- 如两张表都太大时,联表时会把不需要的一些数据行也连接在一起成一张大表,不但消耗更多的时间,也浪费内存,因为联表是数据库层的操作,所以还会增加数据库的负担。此时,用
prefetch_related()
方法更好。
二、MTV与MVC模型
- 这两个东西都是纯理论,没有特别的意思。
1. MTV模型
MTV
- M:models
- T:templates
- V:views
django自称为是MTV框架 本质其实还是MVC
2. MVC模型
- MVC
- M:models
- V:views
- C:controller 路由匹配
三、chioces
参数
chioces
参数的作用是把一些数据信息映射成一个简单的字符串或者数字,在保存数据时只需要保存这些简单的字符串或数字即可,以此可以节省数据库资源。- 取值:
- 只要是
choices
字段类型,在获取值的时候 统一句式:get_字段名_display()
。 若直接以对象点字段的方式,则获取到的是我们自定义chioces
参数的值的每个元组中的第一个元素。
- 只要是
- 插入数据:
- 当我们在插入数据时,若插入
chioces
参数的自定义值中没有的数据,可以插入成功。在使用get_字段名_display()
取值时,因为元组中没有第二个元素,不会报错,取值也只会取到第一个元素。这里不是很好理解,看下面的实例。
- 当我们在插入数据时,若插入
- 实例
# models.py文件中:
class User(models.Model):
username = models.CharField(max_length=64)
password = models.IntegerField()
# 自定义chioces参数的值,一个元组就是一个值,元组第一个元素可以为数字,也可以为字符串,以gender字段的字段类型为准。
gender_choices = (
(1,'男'),
(2,'女'),
(3,'其他'),
)
gender = models.IntegerField(choices=gender_choices) # chioces参数
# views.py文件中:
# 执行插入操作
models.User.objects.create(username='tank',password=123,gender=1)
models.User.objects.create(username='nick',password=123,gender=4) # 可以插入数据成功
# 执行查询操作
user_obj1 = models.User.objects.filter(username='tank').first()
user_obj2 = models.User.objects.filter(username='nick').first()
# 打印信息
print(user_obj1.get_gender_display()) # 结果是: 男
print(user_obj2.get_gender_display()) # 结果是: 4
四、Ajax
Ajax 不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的Web应用程序的技术
Ajax 特点:异步提交,局部刷新
AJAX 最大的作用是在不重新加载整个页面的情况下,可以与服务器交换数据并更新网页的部分内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)-
题外话:
- 每家公司都会有属于这家公司独有的内部管理软件
- 专门用来开发企业内部管理软件框架 ——》 odoo
- odoo框架内部功能实现全部依赖于python2
1. Ajax语法
(1)起手语法
起手:
$.ajax({
# 书写代码
})
(2)Ajax基本语法结构
<scrip> $.ajax({
url:'', // 数据提交的后端地址 不写就是往当前页面提交 也可以写后缀 也可以写全称 跟form表单的actions参数一样
type:'post', // 提交方式 默认是get请求
data:{'i1':$('#d1').val(),'i2':$('#d2').val()}, // 提交的数据
success:function (recv_data) { // 形参recv_data就是异步提交之后后端返回结果
$('#d3').val(recv_data) // 回调机制需要做的事情
}
}) </scrip>
实例
// 前端代码:
$.ajax({
url:'', // 数据提交的后端地址 不写就是往当前页面提交 也可以写后缀 也可以写全称 跟form表单的actions参数一样
type:'post', // 提交方式 默认是get请求
data:{'i1':$('#d1').val(),'i2':$('#d2').val()}, // 提交的数据
success:function (recv_data) { // 形参recv_data就是异步提交之后后端返回结果
$('#d3').val(recv_data) // 回调机制需要做的事情
}
})
// 后端代码:
def xxx(request):
print(request.is_ajax()) # 判断当前请求是否是ajax请求,打印结果: True
# 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') # 给异步回调函数 success
# return redirect('https://www.baidu.com') # 给异步回调函数 success
return render(request,'xxx.html')
- 注意:一旦你使用了ajax,django中必知必会三板斧(
render/HttpResponse/redirect
)都不再作用与页面,而是与recv_data交互,即这三个方法返回到前端的数据都被接收中recv_data中
五、前端传输数据的编码格式
- 前端发到后端的数据都有数据编码格式,针对不同的数据,后端会自动进行不同的处理
- 前端中,只要你的数据满足urlencoded格式,不管你当前的编码格式是什么,django后端都会自动解析,并且根据你的提交方式帮你封装到
request.GET或request.POST
中- urlencoded编码格式对应的数据的格式:
username=jason&password=123
- urlencoded编码格式对应的数据的格式:
1. 常见的编码格式
- urlencoded
- formdata
- application/json
2. form表单发送数据的编码格式
- form标签的控制编码格式的属性:
enctype
(1)urlencoded编码格式
form表单默认编码格式是urlencoded
urlencoded编码格式对应的数据格式:
username=jason&password=123
django后端针对urlencoded数据,会自动解析,帮你封装到
request.POST
中
(2)formdata编码格式
- 传文件时用的编码格式
- 传文件必须做到两件事:
- 必须将其默认的urlencoded换成formdata
- 提交数据方式改为post
- 针对formdata格式的数据,你在浏览器上是无法查看到,因为这时的提交方式肯定是post
- 如果你是一个文件对象,django后端也会自动识别帮你放到
request.FILES
中
(3)json格式
- form表单无法发送json格式的数据 你要想法 你只能借助于ajax。
3. ajax发送数据的编码格式
- ajax能够发送3种格式的数据:
- urlencoded
- formdata
- application/json
(1)urlencoded编码格式
- ajax默认的编码格式也是urlencoded 也就意味着后端django也是会自动解析,并且帮你封装到request.POST`中
(2)formdata编码格式
文件对象的数据,django后端会自动识别并存放在
request.FILES
中Ajax传文件的实例:
牢记实例中的1, 2, 3, 4 四点。
以下MyFormData添加的前3条数据在后端会自动存放在
request.POST
中,最后一个文件数据会在后端自动存放在request.FILES
中。
<scrip>
// 传文件
$('#d1').click(function () {
// 1.先生成一个内置对象
var MyFormData = new FormData();
// 2. 先添加普通的键值
MyFormData.append('username','jason'); // 添加了一组普通的键值对
MyFormData.append('password','123');
MyFormData.append('hobby',['read','run']);
// 3. 添加文件数据
MyFormData.append('myfile',$('#d2')[0].files[0]); // 如何获取input框中文件对象$('#d1')[0].files[0]
// ajax基本语法结构
$.ajax({
url:'',
type:'post',
data:MyFormData,
// 4. 发送文件必须要指定的两个参数(1)(2)
contentType:false, // (1)不适用任何编码 MyFormData对象内部自带编码 django后端能够识别
processData:false, // (2)不要处理数据
success:function (back_data) {
alert(back_data) // 回调机制需要做的事情
}
})
})
</scrip>
(3)application/json编码格式
django后端针对json格式的数据,不会做任何处理,数据怎么来的,只会原封不动的放到
request.body
中,需要你自己手动处理。(即到后端还是二进制类型的json格式的数据)ajax传输json格式数据实例:
注意:实例中的1, 2 两点
<scrip>
$('#d1').click(function () {
$.ajax({
url:'',
type:'post',
contentType:'application/json', // 1.编码格式写法
data:JSON.stringify({'username':'jason','password':'123'}), // 2.序列化
success:function (back_data) {
alert(back_data)
}
})
})
</scrip>
- 后端对前端的ajax传输过来的json格式的数据的反序列化
# 因为ajax传输过来的json格式的数据是二进制类型的json格式,所以:
# 方式一:
import json
json_data = ajax_data.decode('utf-8')
data = json.loads(json_data)
# 方式二:直接使用json.loads , 他会直接把二进制也一起转。
data = json.loads(ajax_data)
六、后端数据的序列化
在实际开发环境中,针对前后端分离的模式,因为此时不能使用django的模板语法,后端返回到前端的数据需要非常多、非常清晰,并且是json格式的数据。如:要返回当前数据来自哪张表,数据要有描述即字典类型,还有等等,我们此时就需要自己手动书写,这样就会非常麻烦,也不保证没有缺漏的数据。
针对上面的问题,通过django中的内置模块
serializers
就可以完美解决了。实例:
from app01 import models
from django.core import serializers # 序列化目的 将数据整合成一个大字典形式 方便数据的交互
def zzz(request): user_queryset = models.User.objects.all()
res = serializers.serialize('json',user_queryset)
return HttpResponse(res)
orm查询优化 MTV和MVC模型 字段的chioces参数 Ajax的更多相关文章
- django----orm查询优化 MTV与MVC模型 choice参数 ajax serializers
目录 orm查询优化 only defer select_related 与 prefetch_related MTV 与 MVC 模型 choice参数 Ajax 前端代码 后端代码 前后端传输数据 ...
- ORM中choices参数(重要)、MTV于MVC模型、多对多关系三种创建方式
choices参数(重要) **使用方式
- Django与AJAX-choice字段-MTV和MVC模型-sweetalert搭建页面
Django中的choice字段 应用的场景: 用户信息举列:如用户性别.婚否.学历.工作状态等可以列举出来供选择的信息 书写models创建表模型: 数据的获取和查询: 总结: "&quo ...
- django ORM 增删改查 模糊查询 字段类型 及参数等
ORM 相关 #sql中的表 #创建表: CREATE TABLE employee( id INT PRIMARY KEY auto_increment , name VARCHAR (), gen ...
- Django-choices字段值对应关系(性别)-MTV与MVC科普-Ajax发json格式与文件格式数据-contentType格式-Ajax搭配sweetalert实现删除确认弹窗-自定义分页器-批量插入-07
目录 models 字段补充 choices 参数/字段(用的很多) MTV与MVC模型 科普 Ajax 发送 GET.POST 请求的几种常见方式 用 Ajax 做一个小案例 准备工作 动手用 Aj ...
- MVC模型与MTV模型
MVC模型: MVC(Model View Controller 模型-视图-控制器)是一种Web架构的模式,它把业务逻辑.模型数据.用户界面分离开来,让开发者将数据与表现解耦,前端工程师可以只改页面 ...
- 2019年6月14日 Web框架之Django_07 进阶操作(MTV与MVC、多对多表三种创建方式、前后端传输数据编码格式contentType、ajax、自定义分页器)
摘要 MTV与MVC 多对多表三种创建方式 ajax ,前后端传输数据编码格式contentType 批量插入数据和自定义分页器 一.MVC与MTV MVC(Model View Controller ...
- Django多对多表的三种创建方式,MTV与MVC概念
MTV与MVC MTV模型(django): M:模型层(models.py) T:templates V:views MVC模型: M:模型层(models.py) V:视图层(views.py) ...
- django ajax MTV与MVC 多对多创建方式
MTV与MVC MTV模型(django): M:模型层(models.py) T:templates V:views MVC模型: M:模型层(models.py) V:视图层(views.py) ...
随机推荐
- yum安装telnet如何开启telnet服务
1.# yum install -y telnet telnet-server xinetd (其中telnet-server是由xinetd管理的,所以得下载xinetd服务) 2.修 ...
- 【MapReduce】二、MapReduce编程模型
通过前面的实例,可以基本了解MapReduce对于少量输入数据是如何工作的,但是MapReduce主要用于面向大规模数据集的并行计算.所以,还需要重点了解MapReduce的并行编程模型和运行机制 ...
- 安装VMWare tools 及安装后/mnt中有hgfs但没共享文件的解决办法
一.首先是安装VMWare tools打开虚拟机软件,在菜单栏‘虚拟机’子菜单下‘安装VMware Tools' 1.以root身份进入Linux 2.此时把linux的/dev/cdrom设备挂载到 ...
- python函数 -- 作用域,异常处理
1.def语句和参数 python定义函数的关键词为def,格式如下: def 函数名([变元],[变元],....) #保存在变元中的值,在函数返回后该变元就会被销毁了. 2.返回 ...
- Hadoop简介及架构
狭义上来说,hadoop就是单独指代hadoop这个软件, 广义上来说,hadoop指代大数据的一个生态圈,包括很多其他的软件 2.hadoop的历史版本介绍 0.x系列版本:hadoop当中最早的一 ...
- Type类的使用
Type类的使用(类反射)通过类获得Type: Type t = typeof(Person)通过实例对象获得类的Type: Type t = p.GetType()获取Type的方法:MethodI ...
- C++多线程基础学习笔记(八)
shared_futrue和futrue_status的用法 shared_futrue是一个类模板,类似于futrue,不同的是它的成员函数get()可以使用多次,因为是复制数据,而futrue的g ...
- C/C++的几个输入流
C: 1.scanf( ) 存在于<stdio.h>(C++为<cstdio>)中,根据stdin读取数据并根据参数格式进行赋值,以第一个非空格字符(空格字符如:空格,制符表, ...
- 正确理解Widget::Widget(QWidget *parent) :QWidget(parent)这句话
原文:https://zhuanlan.zhihu.com/p/31310536 /********原文********/ 最近很多学习Qt的小伙伴在我的微信公众号私信我,该如何理解下面段代码的第二行 ...
- C++ Primer 回炉重铸(一)
过去学C++语法都是用的这本C++Primer第五版 说实话,这本书应该是业界用的最多的一本类似于C++语法的百科全书了.. 但是感觉自己学了这么长时间的C++,语法层次还是不够牢固. 比如templ ...