ORM查询优化

only与defer

  1. res = models.Book.objects.all().values('title')
  2. print(res) # <QuerySet [{'title': '三国演义'}, {'title': '红楼梦'}, {'title': '水浒传'}, {'title': '天龙八部'}]>
  3. for i in res:
  4. print(i,type(i)) # <class 'dict'>
  5. print(i.title) # AttributeError: 'dict' object has no attribute 'title' ,for循环出来就是第一个普通的字典,字典没有点取值的方式

only:查询only后括号内指定的字段,查询一次,之后再点字段不会再查数据库了;如果点的是其他字段,会再次操作数据库;

  1. # 点指定字段
  2. res = models.Book.objects.only('title')
  3. print(res) # 返回的是一个QuerySet对象,列表内是一个个类的对象;
  4. for i in res:
  5. print(i.title)

  1. # 点其他字段
  2. res = models.Book.objects.only('title')
  3. # print(res)
  4. for i in res:
  5. print(i.price)

refer:refer和only互为反关系,按照refer指定字段查找,操作数据库一次,之后对象点指定的属

性,每点一次,操作一次数据库;如果点其他字段,整体只操作一次数据库。


  1. # 点指定字段
  2. res = models.Book.objects.defer('title')
  3. # print(res)
  4. for i in res:
  5. print(i.title)

  1. # 点其他字段
  2. res = models.Book.objects.defer('title')
  3. # print(res)
  4. for i in res:
  5. print(i.price)

select_related与prefetch_related查询优化

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

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

来封装成一个个的对象。这样做的好处就在于跨表也不需要重复的走数据库了,减轻数据库的压力。

select_related括号内可以放多个外键字段,逗号隔开,会将多个外键字段关联的表与当前表全部拼成一张大表。

  1. res = models.Book.objects.select_related('publish')
  2. print(res) # <QuerySet [<Book: Book object>, <Book: Book object>, <Book: Book object>, <Book: Book object>]>
  3. for i in res:
  4. print(i.publish) # 只操作一次数据库
  5. '''
  6. Publish object
  7. Publish object
  8. Publish object
  9. Publish object
  10. '''

一对多的情况:

  1. res = models.Book.objects.select_related('publish')
  2. # print(res)
  3. for i in res:
  4. print(i.publish) # 只操作一次数据库

一对一的情况:

  1. res = models.Author.objects.select_related('author_detail')
  2. # print(res)
  3. for i in res:
  4. print(i.author_detail)
  5. # 内部做的也是联表操作,同一对多一样,也是内连接

多对多的情况:

  1. res = models.Book.objects.select_related('author')
  2. # print(res)
  3. for i in res:
  4. print(i.author)
  5. '''
  6. 报错信息:
  7. django.core.exceptions.FieldError: Invalid field name(s) given in select_related: 'author'. Choices are: publish
  8. '''

prefetch_related:内部是子查询,会自动帮你按步骤查询多张表 然后将查询的结果封装到对象中,

给用户的感觉好像还是连表操作,括号内支持传多个外键字段 并且没有类型限制。

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

  1. res = models.Book.objects.prefetch_related('publish','authors')
  2. # print(res)
  3. for i in res:
  4. print(i.publish,i.authors.all())
  5. '''
  6. Publish object <QuerySet [<Author: Author object>, <Author: Author object>]>
  7. Publish object <QuerySet []>
  8. Publish object <QuerySet []>
  9. Publish object <QuerySet []>
  10. '''

两者之间的优缺点比较

  1. 结合实际情况,看表的数据量的大小,
  2. 两张表都特别大的情况下,连表操作可能耗时更多;

choices参数

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

1.建表

  1. # models.py文件
  2. from django.db import models
  3. # Create your models here.
  4. class User(models.Model):
  5. username = models.CharField(max_length=32)
  6. password = models.BigIntegerField()
  7. gender_choices = (
  8. (1,'男'), # 第一个参数可以是数字,也可以是自定义的字符串
  9. (2,'女'),
  10. (3,'其他'),
  11. )
  12. gender = models.IntegerField(choices = gender_choices)

2.数据库迁移命令 数据录入

这里我们使用的是django自带的测试用的db.sqlite3数据库,并在表中添加数据

菜单栏Tools>Run manage.py Task

django 终端:1.makemigrations 2.migrate

3.测试环境配置及示例分析

  1. from django.test import TestCase
  2. # Create your tests here.
  3. import os
  4. if __name__ == "__main__":
  5. os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day56.settings")
  6. import django
  7. django.setup()
  8. from app01 import models
  9. user_obj1 = models.User.objects.get(pk = 1)
  10. user_obj2 = models.User.objects.get(pk = 4)
  11. # print(user_obj1.gender) # 1
  12. # print(user_obj2.gender) # 4 这里id=4并没有gender对应的性别关系,但不报错。
  13. print(user_obj1.get_gender_display()) # 男 正确的获取方式
  14. print(user_obj2.get_gender_display()) # 4 没有性别的对应关系获取到的还是数字本身

choices参数在实际项目中的表设计

MTV与MVC模型

MTV模型:

django就是MTV框架,但本质还是MVC

MTV:

M:models

T:templates

V:views

MVC:

M:models

V:views

C:controller 路由匹配

MVVM :前端框架,比如:Vue

Ajax简介

AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”。

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

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

AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网

页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)

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

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

了解:

  1. XML也是一门标记语言
  2. 该语法应用场景
  3. 1.写配置文件
  4. 2.可以写前端页面(odoo框架中 erp)
  5. 每家公司都会有属于这家公司独有的内部管理软件
  6. 专门用来开发企业内部管理软件 框架 odoo
  7. odoo框架内部功能实现全部依赖于python2

AJAX常见应用情景

1)搜索引擎根据用户输入的关键字,自动提示检索关键字。

2)还有一个很重要的应用场景就是注册时候的用户名的查重。

其实这里就使用了AJAX技术!当文件框发生了输入变化时,使用AJAX技术向服务器发送一个请求,然后服

务器会把查询到的结果响应给浏览器,最后再把后端返回的结果展示出来。

  • 整个过程中页面没有刷新,只是刷新页面中的局部位置而已!
  • 当请求发出后,浏览器还可以进行其他操作,无需等待服务器的响应!

当输入用户名后,把光标移动到其他表单项上时,浏览器会使用AJAX技术向服务器发出请求,服务器会

查询名为lemontree7777777的用户是否存在,最终服务器返回true表示名为lemontree7777777的用户

已经存在了,浏览器在得到结果后显示“用户名已被注册!”。

  • 整个过程中页面没有刷新,只是局部刷新了;
  • 在请求发出后,浏览器不用等待服务器响应结果就可以进行其他操作;

AJAX的优缺点

优点:

- AJAX请求无须刷新整个页面;

- 两个关键点:1.局部刷新,2.异步请求

- AJAX使用JavaScript技术向服务器发送异步请求;

- 因为服务器响应内容不再是整个页面,而是页面中的部分内容,所以AJAX性能高;

Ajax基本语法结构

$.ajax({ })

  1. // ajax基本语法结构
  2. $.ajax({
  3. url:'', // 数据提交的后端地址 不写就是往当前页面提交 也可以写后缀 也可以写全称 跟actions一样
  4. type:'post', // 提交方式 默认是get请求
  5. data:{'i1':$('#d1').val(),'i2':$('#d2').val()}, // 提交的数据
  6. success:function (data) { // 形参data,就是异步提交之后后端返回的结果,两个data不是同一个
  7. $('#d3').val(data) // 回调机制需要做的事情
  8. }
  9. })
  10. // 注意:使用ajax django三板斧都不再作用与页面 而是与data交互

Ajax基本示例1(实现前后端数据交互)

  1. # urls.py文件
  2. # Ajax在post发送post请求的时候记得注销掉settings.py文件中的中间件
  3. from app01 import views
  4. urlpatterns = [
  5. url(r'^admin/', admin.site.urls),
  6. url(r'^about_ajax/',views.xxx),
  7. ]
  1. # views文件
  2. from django.shortcuts import render,HttpResponse
  3. # Create your views here.
  4. def xxx(request):
  5. # print(request.is_ajax()) # 判断当前请求是否是Ajax请求,返回布尔值
  6. # print(request.POST) # ajax发送的post请求,普通的键值对也在request.POST中获取
  7. # if request.method == 'POST':
  8. if request.is_ajax(): # True
  9. i1 = request.POST.get('i1') # 默认取列表的最后一个元素,
  10. i2 = request.POST.get('i2')
  11. # print(i1,type(i1)) # 字符串类型 1 <class 'str'>
  12. res = int(i1) + int(i2)
  13. return HttpResponse(res) # 把结果给异步回调函数success
  14. return render(request, 'xxx.html')
  1. // 这里直接使用JQuery封装好的方法,就不再用原生的js版本了。
  2. // xxx.html 文件
  3. <!DOCTYPE html>
  4. <html lang="en">
  5. <head>
  6. <meta charset="UTF-8">
  7. <title>Title</title>
  8. <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
  9. </head>
  10. <body>
  11. <input type="text" id="d1"> + <input type="text" id="d2"> = <input type="text" id = "d3">
  12. <button id="d4" style="color:orange">点我发送请求</button>
  13. <script>
  14. $('#d4').on('click',function () {
  15. $.ajax({
  16. url:'',
  17. type:'post',
  18. data:{'i1':$('#d1').val(),'i2':$('#d2').val()}, // 提交数据 data对应的是个字典,里面是键值对
  19. success:function (data) { // 形参data就是异步提交之后后端返回的结果
  20. {#alert(data)#}
  21. $('#d3').val(data) // 后端返回的结果就是这里的data接收的
  22. }
  23. })
  24. })
  25. </script>
  26. </body>
  27. </html>

前后端传输数据编码格式

  1. 前后端交互是一个数据编码格式,针对不同的数据,后端会进行不同的处理。
  2. 一般请求:
  3. request.POST
  4. 文件格式的请求:
  5. request.FILES

发送请求三种编码格式:

1.urlencoded

2.formdata # form表单往后端发文件指定的编码格式

3.application/json # Ajax往后端发送文件指定的编码格式

能朝后端发数据的请求有哪些

  1. a标签href参数 get请求
  2. form表单 get/post
  3. ajax get/post
  4. get请求的数据格式比较单一,这里不做研究。
  5. url?xxx=ooo&yyy=zzz

form表单编码格式及发送文件(发post请求)

第一种编码格式:urlencoded

  1. 1).默认是urlencoded编码
  2. Content-Type: application/x-www-form-urlencoded
  3. urlencoded所对应的数据格式:
  4. username=jason&password=123
  5. django后端针对urlencoded编码格式的数据 会自动解析并且帮你封装到request.POST

第二种编码格式:multipart/form-data

  1. 2). form表单指定enctype="multipart/form-data",
  2. Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryhjKCHQHDmcE62iMQ
  3. 针对formdata格式的数据 你在浏览器上是无法查看到
  4. 如果是一个文件对象,django后端也会自动识别,放到request.FILES

form表单在multipart/form-data编码格式下发送文件

当form表单不指定参数enctype="multipart/form-data"时发生的情况:

代码示例:

  1. from django.shortcuts import render,HttpResponse
  2. def about_form(request):
  3. if request.method=='POST':
  4. print(request.POST) # <QueryDict: {'username': ['zhang'], 'password': ['123']}>
  5. print(request.FILES) # <MultiValueDict: {'myfile': [<InMemoryUploadedFile: ORM查询优化.md (application/octet-stream)>]}>
  6. return render(request,'about_form.html')
  7. '''
  8. 当about_form.html文件中form标签参数不指定enctype="multipart/form-data"时,后端打印结果为:
  9. <QueryDict: {'username': ['zhang'], 'password': ['123'], 'myfile': ['ORM查询优化.md']}>
  10. <MultiValueDict: {}> 无法拿到文件对象
  11. '''
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
  7. <link rel="stylesheet" href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css">
  8. <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
  9. </head>
  10. <body>
  11. <form action="" method="post" enctype="multipart/form-data">
  12. username:<input type="text" name="username">
  13. password:<input type="text" name="password">
  14. <input type="file" name="myfile">
  15. <input type="submit">
  16. </form>
  17. </body>
  18. </html>
  1. 3).form表单无法发送json格式的数据,只能借助于ajax

ajax传输数据的编码格式及发送文件(post请求)

ajax发送

1.urlencoded

2.application/json post请求下前端发送json格式数据

3.formdata

第一种编码格式:默认的urlencoded编码格式

  1. 1).Content-Type: application/x-www-form-urlencoded; charset=UTF-8
  2. ajax默认的编码格式也是urlencoded,也就意味着后端django也是将数据解析到request.POST



在涉及到前后端交互的时候 一定要做到数据的格式与编码格式一致

第二种编码格式:html文件中添加contentType参数为application/json,往后端发json格式数据

  1. 2).django后端针对application/json编码格式的数据,不会做任何处理,数据怎么来的,只会原封不动的放到request.body
前端js 后端json
stringify dumps
parse loads

第三种编码格式:multipart/form-data

  1. 数据传到后端直接分成两个部分,数据信息放在POST中,文件放在FILES

Ajax发送json格式数据

代码示例:

  1. # views.py 文件
  2. from django.shortcuts import render,HttpResponse
  3. def about_form(request):
  4. if request.method=='POST':
  5. print(request.body) # b'{"username":"zhang","passowrd":"123"}'
  6. json_bytes = request.body
  7. import json
  8. # 方式1:
  9. # user_dic = json.loads(json_bytes.decode('utf8'))
  10. # print(user_dic) # {'username': 'zhang', 'passowrd': '123'}
  11. # 方式2:
  12. user_dic = json.loads(json_bytes) # 自动帮你解码家反序列化
  13. print(user_dic,type(user_dic)) # {'username': 'zhang', 'passowrd': '123'} <class 'dict'>
  14. return render(request,'about_form.html')
  1. <!--about_form.html文件-->
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>Title</title>
  7. <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
  8. </head>
  9. <body>
  10. <button id="d1">点我发送json格式数据</button>
  11. <script>
  12. $('#d1').click(function () {
  13. $.ajax({
  14. url:'',
  15. type:'post',
  16. contentType:'application/json', // 不写默认编码格式为urlencoded,form表单enctype指定编码格式
  17. data:JSON.stringify({'username':'zhang','passowrd':'123'}),
  18. success:function (data) {
  19. alert(123)
  20. }
  21. })
  22. })
  23. </script>
  24. </body>
  25. </html>

Ajax发送文件格式数据

借助于内置对象new,该对象即可以携带文件数据,同样也支持普通的键值对

代码示例:

  1. from django.shortcuts import render,HttpResponse
  2. def about_form(request):
  3. if request.method=='POST':
  4. # 数据传到后端直接分成两个部分,分别放在POST中,和FILES中
  5. print(request.POST) # <QueryDict: {'username': ['zhang'], 'password': ['123']}>
  6. print(request.FILES) # <MultiValueDict: {'myfile': [<InMemoryUploadedFile: ORM查询优化.md (application/octet-stream)>]}>
  7. return render(request,'about_form.html')
  1. <!--about_form.html文件-->
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>Title</title>
  7. <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
  8. </head>
  9. <body>
  10. username:<input type="text">
  11. password:<input type="password">
  12. myfile:<input type="file" id="d1" name="myfile">
  13. <button id="d2">点我发送文件</button>
  14. <script>
  15. $('#d2').click(function () {
  16. // 先生成一个内置对象
  17. var MyFormData = new FormData();
  18. // 1. 先添加普通的键值
  19. MyFormData.append('username','zhang'); // 添加了一组普通的键值对
  20. MyFormData.append('password','123');
  21. // 2. 添加文件数据
  22. MyFormData.append('myfile',$('#d1')[0].files[0]); // 如何获取input框中文件对象$('#d1')[0].files[0]
  23. $.ajax({
  24. url:'',
  25. type:'post',
  26. data:MyFormData,
  27. // 发送文件必须要指定的两个参数
  28. contentType:false, // 不使用任何编码 MyFormData对象内部自带编码 django后端能够识别
  29. processData:false, // 不要处理数据
  30. success:function (data) {
  31. }
  32. })

序列化

序列化目的:将数据整合成一个大字典形式,方便前后端数据的交互,实现方便前后端分离。

代码示例:

  1. from app01 import models
  2. from django.core import serializers
  3. def back_dict_in_list(request):
  4. user_queryset = models.User.objects.all()
  5. # [{username:...,password:...,hobby:...,},{},{},{}]
  6. # user_list = []
  7. # for data in user_queryset:
  8. # 数据量比较大的情况下书写麻烦
  9. # user_list.append(
  10. # {'username':data.username,
  11. # 'password':data.password,
  12. # 'gender':data.get_gender_display(),
  13. #
  14. # }
  15. # )
  16. user_list = serializers.serialize('json', user_queryset) # 能指定序列化到前端的数据格式
  17. return HttpResponse(user_list)

本次内容总结点我

django07:sweetalert、bulk_create批量插入、分页器

django之ORM的查询优化、Ajax 06的更多相关文章

  1. python自动化开发-[第十八天]-django的ORM补充与ajax,分页器

    今日概要: 1.ORM一对多,多对多 2.正向查询,反向查询 3.聚合查询与分组查询 4.F查询和Q查询 5.ajax 6.分页器 一.ORM补充: django在终端打印sql语句设置: LOGGI ...

  2. Django之ORM操作

    Django之ORM操作 前言 Django框架功能齐全自带数据库操作功能,本文主要介绍Django的ORM框架 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计 ...

  3. django创建ORM模型、通过ORM模型操作单个表、ORM模型常用字段

    一.ORM简介 ORM ,全称Object Relational Mapping,中文叫做对象关系映射,通过ORM我们可以通过类的方式去操作数据库,而不用再写原生的SQL语句.通过把表映射成类,把行作 ...

  4. python——Django(ORM连表操作)

    千呼万唤始出来~~~当当当,终于系统讲了django的ORM操作啦!!!这里记录的是django操作数据库表一对多.多对多的表创建及操作.对于操作,我们只记录连表相关的内容,介绍增加数据和查找数据,因 ...

  5. Python’s SQLAlchemy vs Other ORMs[转发 3]Django's ORM

    Django's ORM Django is a free and open source web application framework whose ORM is built tightly i ...

  6. 将SALT_STACK的JOB-CACHE放到数据库中,而建库用DJANGO的ORM完成

    下面包括了SALT_MASTER的配置,及DJANGO的ORM里更改默认表名称,更改默认字段名称(里面有个RETURN),更改默认ID索引... 一个下午有和它磨来磨去... 感谢鹏龙,感谢高远..: ...

  7. Django:之ORM、CMS和二维码生成

    Django ORM Django 的数据库接口非常好用,我们甚至不需要知道SQL语句如何书写,就可以轻松地查询,创建一些内容,所以有时候想,在其它的地方使用Django的 ORM呢?它有这么丰富的 ...

  8. Django的ORM实现数据库事务操作

    在Django中实现数据库的事务操作 在学习MySQL数据库时,MySQL数据库是支持原子操作的. 什么是数据库的原子操作呢??打个比方,一个消费者在一个商户里刷信用卡消费. 交易正常时,银行在消费者 ...

  9. 第十九章 Django的ORM映射机制

    第十九章 Django的ORM映射机制 第一课 Django获取多个数据以及文件上传 1.获取多选的结果(checkbox,select/option)时: req.POST.getlist('fav ...

随机推荐

  1. Redis(1.5)Redis配置文件(4.0.14)

    4.0.14 常用配置 bind 127.0.0.1 # 默认绑定本地,不写的话任何地址都可以访问 protected-mode yes #保护模式,如果没有设置bind 配置地址,也没有设置任何密码 ...

  2. MySql查看时间

    select now();命令查看MySql时间(包括时分秒) select current_date();命令查看MySql时间(不包括时分秒) 在代码中,创建时间.修改时间字段的jdbc语句也可以 ...

  3. 2019年9月训练(贰)区间DP (luogu 4290)

    区间DP luogu 4290 明显的区间DP. 定义 dp[l][r][k]/*表示区间[l,r]能否凑成k(W,I,N,G)字符*/mp['W']=1;mp['I']=2;mp['N']=3;mp ...

  4. PHP 协程:Go + Chan + Defer

    Swoole4为PHP语言提供了强大的CSP协程编程模式.底层提供了3个关键词,可以方便地实现各类功能. Swoole4提供的PHP协程语法借鉴自Golang,在此向GO开发组致敬 PHP+Swool ...

  5. python-迭代器实现异步(在串行中)

    import timedef consumer(name): print('%s 准备吃包子啦!' %name) while True: baozi = yield #yield不但可以返回值还可以接 ...

  6. (四)创建基于maven的javaFX+springboot项目,用户界面与后台逻辑分离方式

    下面来介绍创建maven的javaFX+springboot项目,基于用户界面与后天逻辑分离的方式,用户界面使用fxml文件来常见,类似于jsp,可以引入css文件修饰界面 maven依赖 <d ...

  7. 爬虫中什么是requests

    print(response.text) #响应的信息 print(response.headers) #获取响应头 print(response.status_code) #响应状态码 print( ...

  8. Laravel save部分字段失效的bug问题解决

    问题描述:今天在编写api的更新部分,发现有部分字段怎么更新都更新不上去. 问题排查: 经过多次测试,发现每次提交只能更新部分字段,字段分别为:id,user_id,device_room_id,na ...

  9. vue-loading图

    父组件给子组件src地址: columns(){ return [ {'title': '图片', 'key': 'img', render(h, {row}){ return h(LoadingIm ...

  10. vue-无限滚动

    <ul class="infinite-list" v-infinite-scroll="load" style="overflow:auto& ...