目录
orm查询优化
惰性查询, 目的: 减少不必要的数据库操作, 降低数据库的压力
缓存数据库, redis, mongodb, 目的: 缓解主库压力, 相当于一个非常大的内存, 速度快同时也能做持久化
能少走一次数据库就少走一次
only与defer
only:
res = models.Book.objects.only('title')
print(res) # <QuerySet [<Book: 红楼梦>, <Book: 西游记>, ...]>
for i in res:
print(i.title) # 查1次数据库
print(i.price) # 查5次数据库
defer:
res = models.Book.objects.only('title')
for i in res:
print(i.title) # 查5次数据库
print(i.price) # 查1次数据库
selected_related与prefetch_related
selected_related:
- select_related括号内只能放外键字段,
- 并且外键字段只能是多对一或者一对一, 不能是多对多,
- 内部是自动联表操作, 会将括号中的外键字段所关联的表与当前表自动拼接成一张表,
- 然后将表中的一条条数据封装成一个个对象, 使跨表查询也不需要重复走数据库,
- 括号中可以放多个外键字段, 会将全部外键字段关联的表与当前表拼成一张大表
res = models.Book.objects.all()
for i in res:
print(i.publish) # 查询外键信息时, 需查询5次数据库
res = models.Book.objects.select_related('publish')
for i in res:
print(i.title) # 查1次数据库
print(i.publish) # 查1次数据库
prefetch_related:
res = models.Book.objects.prefetch_related('publish', 'authors')
for i in res:
print(i.publish) # 查3次数据库
print(i.authors.all()) # 查3次数据库
小结
selected_related: 耗时在数据库层面的联表操作上
当两张表特别大时, selected_related花费时间可能更多
MTV与MCV模型
django自称为MTV框架, 本质还是MVC
MTV:
- M: models
- T: templates
- V: views
MVC:
- M: models
- V: views
- C: controllar, 包含urls.py, 路由匹配
choices参数
性别, 学历等字段可能性都是能完全列举的,
存数字, 取的时候按照提前设定的对应关系取出真正的数据
migrations文件夹下必须要有一个__init__.py
文件, 否则会报错: No changes detected
'''
class User(models.Model):
...
gender_choice = (
(1, '男'),
(2, '女'),
(3, '其他'),
)
gender = models.IntegerField(choices=gender_choice)
from app01 import models
user_obj1 = models.User.objects.get(pk=1)
user_obj2 = models.User.objects.get(pk=4)
print(user_obj1.get_gender_display()) # 男
print(user_obj2.get_gender_display()) # 4
如果存储的数字不在提前设定的对应关系中
能够正常存储, 也能够正常获取
choices字段类型获取对应关系值的句式: get_字段名_display()
弱限制, 没有对应关系时, 获取的结果为表中实际结果
对应关系中的第一个参数不一定是数字, 也可以是字符串
'''
ajax简介
XML
xml也是一门标记语言, 应用场景:
AJAX
最大的优点是在不重新加载整个页面的情况下, 可以与服务器交换数据并更新部分网页内容
同步交互: 客户端发出一个请求后, 需要等待服务器响应结束后, 才能发出第二个请求
异步交互: 客户端发出一个请求后, 无需等待服务器响应结束后, 就能发出第二个请求
'''
1. 页面上有三个input框
2. 前两个框@R_404_5817@, 并将输入的数字用post请求提交到后端, 最后一个框展示两数之和
3. 要求页面不刷新
'''
'''
1. 页面上有三个input框
2. 前两个框@R_404_5817@, 并将输入的数字用post请求提交到后端, 最后一个框展示两数之和
3. 要求页面不刷新
def ajax(request):
# print(request.is_ajax()) # 判断当前请求是否是ajax请求
# print(request.POST) # ajax发送的post请求, 普通的键值对也在request.POST中
if request.is_ajax():
d1 = request.POST.get('d1')
d2 = request.POST.get('d2')
res = int(d1) + int(d2)
return HttpResponse(res) # 结果返回给异步回调函数, 一旦使用ajax请求, 数据只与回调函数交互
return render(request, 'ajax.html')
<script>
$('#d4').on(
'click', function () {
// 开启ajax语法句式:
$.ajax({
url: '', // 控制数据的后端地址, 和form表单中的action用法一样
type: 'post', // 控制数据提交方式, 不写默认是get请求
data: {'d1': $('#d1').val(), 'd2': $('#d2').val()}, // 提交的数据
success: function (data) { // data为异步提交数据后, 后端处理数据的返回结果
$('#d3').val(data) // 回调函数处理返回结果
}
})
}
)
</script>
'''
前后端数据交互的编码格式
a标签的href参数: get请求
form表单: get/post请求, post请求无法发送json格式数据
ajax: get/post请求, post请求默认编码格式为urlencoded
get请求数据格式为单一格式: url?x=a&y=b
post请求的三种数据编码格式
- urlencoded, multipart/formdata, application/json
- 查看请求方式: f12-->Network-->Headers-->Request Headers-->Content-Type
- 查看请求原数据: ...-->Form Data-->view source
- django针对urlencoded数据, username=jason&password=123, 会自动解析并封装到request.POST中
- django针对multipart/formdata数据, 在浏览器中无法查看, 但是会将满足urlencoded的数据解析到request.POST中, 将文件对象解析到request.FILES中
- 发送json格式数据只能借助ajax
- 在涉及前后端交互时, 要做到数据的格式与编码的格式一致
'''
<script>
$('#d4').on(
'click', function () {
$.ajax({
url: '',
type: 'post',
contentType: 'application/json', // post请求发送json数据需要的参数及参数值
data: JSON.stringify({'username': 'jason', 'password': '123'}), // 前端数据使用JSON.stringify序列化为json格式
success: function (data) {
alert(data.username)
}
})
}
)
</script>
def ajax(request):
from django.http import JsonResponse
import json
if request.is_ajax():
json_bin = request.body # 获取json格式二进制数据
json_str = json_bin.decode('utf8') # 解码
user_dic = json.loads(json_str) # 反序列化
return JsonResponse(user_dic) # JsonResponse会自动将后端的字典转换成前端的object类型数据
return render(request, 'ajax.html')
'''
ajax发送文件格式数据
Ajax传文件需要借助js中的内置对象
js实例化对象的关键字: new
'''
<script>
$('#d1').on(
'click',
function () {
var myFormData = new FormData(); // 实例化得到myFormData对象
myFormData.append('username', 'jason'); // 添加普通键值数据
myFormData.append('myfile', $('#d2')[0].files[0]); // 获取input框中文件对象, 并添加到myFileData对象中
$.ajax({
...,
data: myFormData,
contentType: false, // 不使用myFormData对象内部自带的编码, 类似于json.dumps自动转码中文
processData: false, // 设置浏览器不处理发送的数据
...
})
}
)
</script>
def ajax(request):
if request.is_ajax():
print(request.POST) # <QueryDict: {'username': ['jason']}>
print(request.FILES) # <MultiValueDict: {'myfile': [<...: 20天背完四级核心词汇.pdf ...>]}>
...
'''
django内置的序列化模块
drf: django restframework
序列化的目的: 将数据整合成一个大字典的形式, 方便前后端分离之后数据的交互
def serialize(request):
from django.core import serializers
user_queryset = models.User.objects.all()
res = serializers.serialize('json', user_queryset) # json为序列化的数据格式
return HttpResponse(res)
# [{"model": "app01.user", "pk": 1, "fields": {"username": "jason", "password": 123, "gender": 1}}, ...]
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。