Django 07
ORM查询优化
- 就是要尽可能减少对数据库的访问次数
only与defer(单表)
- only方法内传入是什么字段, 则拿到的对象就只具有什么属性, 如果获取对象的其他属性, 也可以拿到, 只不过内部要再访问数据库进行查询
- defer方法内传入什么字段, 则拿到的对象就不具有什么属性, 如果获取对象的该属性, 也可以拿到, 只不过内部要再访问数据库进行查询
- only与defer互为反关系
# only
book_obj = models.Book.objects.filter(pk=1).only('title').first()
print(book_obj.title) # 直接获取
print(book_obj.price) # 需要访问数据库查询
# defer
book_obj = models.Book.objects.filter(pk=1).defer('title').first()
print(book_obj.title) # 需要访问数据库查询
print(book_obj.price) # 直接获取
select_related与prefetch_related(跨表)
_related: 表明是和 "表关系" 相关的方法
select_related 方法内部是自动连表操作, 会将传入的外键字段关联的表, 与当前的表拼接起来, 支持一对一和一对多表关系, 支持传入多个外键字段
prefetch_related 内部是子查询操作, 按步骤查询多张表, 支持多对多表关系, 支持传入多个外键字段, 且每增加一个字段, 查询次数增加一次
select_related方法耗时在连表上, 当表比较大的时候, 连表会比较耗时
prefetch_related方法耗时在查询次数上
# select_related
# 括号内只能放外键字段, 且外键字段类型是能是一对一或者一对多
# 内部是自动连表操作, 会将括号内外键字段关联的表, 与当前表拼接起来
# 括号内可以放多个外键字段, 用逗号隔开
# 耗时: 连表操作上
book_obj = models.Book.objects.filter(pk=1).select_related('publish').first()
print(book_obj.publish.name) # 访问一次数据库
book_obj = models.Book.objects.filter(pk=1).select_related().first()
print(book_obj.publish.name) # 访问两次数据库
# prefetch_related
# 内部是子查询操作, 按步骤查询多个表, 然后将查询的结果封装到对象中
# 括号内可放对个外键字段, 且支持多对多外键
# 每放一个字段, 就会多查询一张表
# 耗时: 查询次数上
book_obj = models.Book.objects.filter(pk=4).prefetch_related('publish', 'authors').first()
print(book_obj.publish.name)
print(book_obj.authors.all())
choices参数
- 针对字段的数据范围是可确定的, 如性别, 学历等, 具有该参数的字段相当于MySQL中的enum枚举
# User表模型类
class User(models.Model):
username = models.CharField(max_length=255)
password = models.CharField(max_length=255)
# 创建数字和学历对应关系的元祖
edu_level_choices = (
(1, 'bachelor'),
(2, 'master'),
(3, 'doctor'),
(4, 'others')
)
# 将元祖赋值给choices参数, 字段类型为int
edu_level = models.IntegerField(choices=edu_level_choices)
- 学历数字不在我们定义好的匹配关系中可以正常存储
+----+----------+----------+-----------+
| id | username | password | edu_level |
+----+----------+----------+-----------+
| 1 | alpha | 111 | 1 |
| 2 | bravo | 111 | 2 |
| 3 | charlie | 111 | 3 |
| 4 | delta | 111 | 4 |
| 5 | echo | 111 | 5 |
+----+----------+----------+-----------+
- 当存在对应关系时, 通过
对象.get_choices字段_display()
获取数字对应的值 - 不存在对应关系时, 该方法也不会报错, 返回的还是该字段对应的数字
# 1.存在对应关系时
user_obj1 = models.User.objects.filter(pk=1).first()
print(user_obj1.edu_level) # 1
print(user_obj1.get_edu_level_display()) # bachelor
# 2.不存在对应关系时
user_obj5 = models.User.objects.filter(pk=5).first()
print(user_obj5.edu_level) # 5
print(user_obj5.get_edu_level_display()) # 5
- 不一定要用数字来建立对应关系, 也可以用字符串
MTV与MVC模型
- MTV: models, templates, views
- MVC: models, views, controller (路由匹配)
Ajax简介
- Asyn JavaScript and XML
- Ajax可以在不页面不刷新情况下, 实现和数据库进行交互
- 同步交互: 客户端发送一个请求后, 需要等待服务器响应结束后, 才能发送第二个请求
- 异步请求: 客户端发送一个请求后, 不需要等待服务器响应结束, 就能发送第二个请求
- 三个必备参数, 一个回调函数
- url: 提交的地址, 默认是朝当前页面提交
- type: 提交的方式, 默认是get请求
- data: 朝后端提交的数据
- success函数, 函数的参数data接收的后端返回的数据
# 利用ajax实现页面不刷新的情况下, 现在输入的两个数的和
def ajax(request):
# 判断当前请求是否ajax请求
if request.is_ajax():
# print(request.POST) # ajax请求发送的数据也在request.POST当中
v1 = int(request.POST.get('v1'))
v2 = int(request.POST.get('v2'))
res = v1 + v2
return HttpResponse(res) # 只要有ajax, 三板斧就只返回给ajax的回调函数
return render(request, 'ajax_page.html')
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ajax test</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<input type="text" id="d1">+<input type="text" id="d2">=<input type="text" id="d3">
<button id="d4">提交</button>
<script>
$('#d4').on('click', function () {
// 开启ajax语法句式
$.ajax({
url: '', // 数据提交的后端地址, 不写就是往当前页面提交
type: 'post', // 提交方式, 默认还是get请求
data: {'v1': $('#d1').val(), 'v2': $('#d2').val()}, // 向后端提交的数据
success: function (data) { // 形参data是后端返回的结果
$('#d3').val(data)
}
})
})
</script>
</body>
</html>
前后端传输数据编码格式
三种数据编码格式
- urlencoded
- formdata
- application/json
前端向后端发送数据:
- a标签 get请求
- form表单 get/post请求 (urlencoded, form-data)
- ajax get/post请求 (urlencode, form-data, json)
form表单发送文本
编码:
Content-Type: application/x-www-form-urlencoded
数据格式:
username='bigb'&password='123'
后端针对urlencoded数据, 会自动解析并封装到request.POST中
form表单发送文件 ( enctype='multipart/form-data)
- 编码格式:
Content-Type: multipart/form-data
- 数据格式:
浏览器查看不到
- 后端对于form-data文件数据, 会自动解析并保存到request.FILES中
- 编码格式:
前后端交互时候, 一定确保数据格式与编码格式一致
Ajax传输Json数据格式
ajax默认的编码格式也是:
Content-Type: application/x-www-form-urlencoded
, 因此也会封装到request.POST中ajax默认是发送urlencoded编码格式的数据, 如果想发送json数据格式, 需要加一个参数:
contentType: 'application/json'
$('#d1').on('click', function () {
$.ajax({
url: '',
type: 'post',
// 指定编码方式为: application/json
contentType: 'application/json',
data: JSON.stringify({'username': 'bigb', 'password': '123'}),
success: function (data) {
alert(123)
}
})
})
- django后端会将前端发送的json格式数据(二进制)原封不动的放到request.body中, 注意, 是二进制数据!!!
def test(request):
print(request.body) # b'{"username":"bigb","password":"123"}'
return render(request, 'test.html')
Ajax传输文件数据
- ajax传输文件数据需要借助js内置对象FormDate
- FormData对象既可以传文件对象, 也可以传普通的键值对
- 内置对象传文件必须要指定两个参数
- contentType: false
- processData: false
def test(request):
print(request.POST) # <QueryDict: {'username': ['bigb'], 'password': ['123']}>
print(request.FILES) # <MultiValueDict: {'upload_file': [<InMemoryUploadedFile: githublogo.jpg (image/jpeg)>]}
return render(request, 'test.html')
username:<input type="text" name="username">
password:<input type="password" name="password">
upload_file:<input type="file" name="upload_file" id="d2">
<button id="d1">提交</button>
<script>
$('#d1').on('click', function () {
// 1.先生成一个内置对象
let MyFormData = new FormData
// 2.添加普通键值数据
MyFormData.append('username', 'bigb')
MyFormData.append('password', '123')
// 3.获取并添加文件对象
MyFormData.append('upload_file', $('#d2')[0].files[0])
$.ajax({
url: '',
type: 'post',
data: MyFormData,
// 发送文件必须要指定两个参数
contentType: false, // 不使用任何编码, MyFormData内部自带编码
processData: false, //不要处理数据
success: function (data) {
alert(123)
}
})
})
</script>
序列化模块
- 后端数据(一般是字典或者列表套字典)序列化后发送给前端, 实现前后端分离
- serialize()方法可以序列化queryset对象
- 第一个参数: 'json'
- 第二个参数: queryset对象
from django.core.serializers
# serialize()方法可以序列化queryset对象
def test1(request):
user_queryset = models.User.objects.all()
# 第一个参数: 数据格式json, 第二个参数: queryset对象
res = serializers.serialize('json', user_queryset)
return HttpResponse(res)
'''
[{"model": "app01.user", "pk": 1, "fields": {"username": "alpha", "password": "111", "edu_level": 1}}, {"model": "app01.user", "pk": 2, "fields": {"username": "bravo", "password": "111", "edu_level": 2}}, {"model": "app01.user", "pk": 3, "fields": {"username": "charlie", "password": "111", "edu_level": 3}}, {"model": "app01.user", "pk": 4, "fields": {"username": "delta", "password": "111", "edu_level": 4}}, {"model": "app01.user", "pk": 5, "fields": {"username": "echo", "password": "111", "edu_level": 5}}]
'''
Django 07的更多相关文章
- Django 07 Django模型基础2 (常用查询和多表关联)
Django 07 Django模型基础2 (常用查询和多表关联) 一.常用查询 #查找数据 def search_user(request): #获取 rs = User.objects.first ...
- day64 Pyhton 框架Django 07
day67 内容回顾 视图 1. CBV 定义 from django.views import View class Addpub(View): def get(self,request): sel ...
- 07: Django 使用ldap登录、注销等
目录:Django其他篇 01:Django基础篇 02:Django进阶篇 03:Django数据库操作--->Model 04: Form 验证用户数据 & 生成html 05:Mo ...
- Django框架07 /cookie和session
Django框架07 /cookie和session 目录 Django框架07 /cookie和session 1. django请求生命周期 2. cookie 3. session 4. 总结 ...
- Django REST Framework API Guide 07
本节大纲 1.Permissions 2.Throttling Permissions 权限是用来授权或者拒绝用户访问API的不同部分的不同的类的.基础的权限划分 1.IsAuthenticated ...
- Django 2.0 学习(07):Django 视图(进阶-续)
接Django 2.0 学习(06):Django 视图(进阶),我们将聚焦在使用简单的表单进行处理和精简代码. 编写简单表单 我们将用下面的代码,来替换之前的detail模板("polls ...
- 07 - Django应用第四步
知识点 1) 表单的编写 CSRF问题 forloop.counter 2) 视图函数的知识 GET和POST HttpResponseRedirect的使用 reverse的使用 3) 通用视图 C ...
- 07 Django组件-中间件
中间件 方式一:函数式:中间件[middleware],也叫钩子方法[钩子函数],hook Django中的中间件是一个轻量级.底层的插件系统,可以介入Django的请求和响应处理过程,修改Djang ...
- 07.Django学习之model进阶
一 QuerySet 可切片 使用Python 的切片语法来限制查询集记录的数目 .它等同于SQL 的LIMIT 和OFFSET 子句. >>> Entry.objects.all( ...
随机推荐
- springMVC-MyBatis-Mysql 环境下, 返回时间格式不是指定格式
在数据库中的时间是: 比如: 2018-04-06:12;23:34. 但是mybatis查询出来以后是下面的格式. {"updatedTime":{"date" ...
- 🔥「课代表」帮你总结了全网最全的Redis知识点
你知道的越多,你不知道的越多 点赞再看,养成习惯 GitHub上已经开源 https://github.com/JavaFamily 有一线大厂面试点脑图.个人联系方式和人才交流群,欢迎Star和指教 ...
- 06_K-近邻算法
k-近邻算法 算法介绍 定义: 如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一类别,则该样本也属于这个类别. 计算距离公式:欧式距离 (两点之间距离) 需要做标准化 ...
- 11.13的C++##不想写结构,更不爱指针
//2019.11.13 卑微的Loving-Q瞎写的程序 报错请更改VS中的SDL检查// 我要去嗨了,在线卑微 1 #include<iostream> #include<std ...
- spring security进阶 使用数据库中的账户和密码认证
目录 spring security 使用数据库中的账户和密码认证 一.原理分析 二.代码实现 1.新建一个javaWeb工程 2.用户认证的实现 3.测试 三.总结 spring security ...
- Openlayers ol.interaction.Select取消默认选中效果
说明: 在使用ol.interaction.Select进行点击查询时,默认会把点击选中的要素显示在地图上 我的需求是做轨迹回放,并可以点击轨迹上某一点,进行查询.这时候如果重新播放轨迹,会发现这个选 ...
- mysql8.0.13安装、使用教程图解
mysql8.0.13安装.使用教程图解 MySQL是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Manageme ...
- 转。http,状态码详解
转自konglingbinHTTP状态码详解:https://www.cnblogs.com/klb561/p/9205867.html HTTP状态码(HTTP Status Code)是用以表示网 ...
- Fortran文件读写--查找内容
program ex implicit none character(len=) A(),B(),C() !A异常.B已开挖.C需标记 integer i,j,N1,N2,count !N1是10号文 ...
- ELK 相关问题
1.ndex has exceeded [1000000] - maximum allowed to be analyzed for highlighting 详细报错内容: {"type& ...