一、Q查询进阶操作

这里主要就是让查询数据的时候,可以使用input获取的信息,进行用户交互。

from django.db.models import Q
q_obj = Q() # 1.产生q对象
q_obj.connector = 'or' # 默认多个条件的连接是and可以修改为or
q_obj.children.append(('pk', 1)) # 2.添加查询条件
q_obj.children.append(('price__gt', 2000)) # 支持添加多个
res = models.Book.objects.filter(q_obj) # 查询支持直接填写q对象
print(res)

二、ORM查询优化

  • 1.ORM的查询默认都是惰性查询(当我们不执行打印操作的时候,ORM语句不会执行,想要看到这个现象需要打开日志功能,即在配置文件中进行配置)
  • 2.ORM的查询自带分页处理(可以通过日志展示的代码查看,日志返回的sql代码后端会有一个limit)
  • 3.only与defer

only

前置说明

这里需要做一些具体的说明,方便大家理解only和defer。

当我们在Django中执行ORM操作进行数据库查询的时候,其实内部的代码把所有的数据库中的记录,都封装到了ORM操作的对象中去了,因此我们可以通过点的方式或是索引等方式查询到对应的数据。

但是当遇到查询的时候需要查询不在条件中的记录时,就需要执行sql语句进行查询了。

比如我们在查询的时候,需要的结果在外键对应的表中,这时候去外键对应的表中查询数据,就需要执行sql语句进行查询,并且查询一条记录需要执行一次sql语句

而我们的only的作用是把写在括号内的参数中的字段的值封装到对象中,让后续查找的时候 不需要执行sql语句进行查询,加快执行速度。或是起到一个减少代码封装的数据量,加快运行的作用。

而defer则是和only相反,写在括号内的字段值不会被封装到对象中,别的字段反而会被封装到对象中。

only
'''数据对象+含有指定字段对应的数据'''
# res = models.Book.objects.only('title', 'price')
# print(res) # queryset [数据对象、数据对象]
# for obj in res:
# print(obj.title) # 点击括号内填写的字段 不走SQL查询
# print(obj.price)
# print(obj.publish_time) # 可以点击括号内没有的字段获取数据 但是会走SQL查询 defer
res = models.Book.objects.defer('title', 'price')
# print(res) # queryset [数据对象、数据对象]
for obj in res:
# print(obj.title) # 点击括号内填写的字段 走SQL查询
# print(obj.price)
print(obj.publish_time) # 点击括号内没有的字段获取数据 不走SQL查询
  • 4.select_related与prefetch_related

​ select_related括号内填写一对多、一对一字段 自动连表然后继续数据封装

​ prefetch_related括号内填写一对多、一对一字段 基于子查询然后封装数据

	# res = models.Book.objects.all()
# for obj in res:
# print(obj.publish.name) # 每次查询都需要走SQL
# res = models.Book.objects.select_related('authors') # 先连表后查询封装
# res1 = models.Author.objects.select_related('author_detail') # 括号内不支持多对多字段 其他两个都可以
# print(res1)
# for obj in res:
# print(obj.publish.name) # 不再走SQL查询 res = models.Book.objects.prefetch_related('publish') # 子查询
for obj in res:
print(obj.publish.name)

案例截图

三、ORM事务操作

"""
1.事务的四大特性(ACID)
原子性、一致性、隔离性、持久性
2.相关SQL关键字
start transaction;
rollback;
commit;
savepoint;
3.相关重要概念
脏读、幻读、不可重复读、MVCC多版本控制...
"""
django orm提供了至少三种开启事务的方式
方式1:配置文件的数据库相关配置中添加键值对
全局有效
"ATOMIC_REQUESTS": True
ps:每次请求所涉及到的orm操作同属于一个事务
方式2:装饰器
局部有效,这个视图函数内的一些orm操作属于一个事务
from django.db import transaction
@transaction.atomic
def index():pass
方式3:with上下文管理
局部有效,写在with下方的orm操作属于一个事务
from django.db import transaction
def reg():
with transaction.atomic():
pass

ps:这里的三种方法有个小区别,前面两种方式执行事务,遇到返回值类型不对,orm操作雀食是可以正常执行的,但是with上下文管理的方式操作事务的话,则不行,操作会回退。

四、ORM常用字段类型

名称 含义
AutoField() Int自增列 必须填入参数 primary_key=True 当model中如果没有自增列 则自动会创建一个列名为id的列
CharField() 字符类型 必须提供max_length参数 max_length表示字符长度
IntegerField() 一个整数类型 范围在 -2147483648 to 2147483647 (一般不用它来存手机号(位数也不够) 直接用字符串存)
BigIntegerField() 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807
DateField() 日期字段 日期格式 YYYY-MM-DD 相当于Python中的datetime.date()实例
DateTimeField() 日期时间字段 格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] 相当于Python中的datetime.datetime()实例
DecimalField() 10进制小数 参数 max_digits 小数总长度 decimal_places,小数位长度
EmailField() 字符串类型 Django Admin以及ModelForm中提供验证机制
BooleanField() 布尔值类型 传布尔值存数字0或1
TextField() 文本类型 存储大段文本
FileField() 字符串 路径保存在数据库 文件上传到指定目录
参数 upload_to = " " 上传文件的保存路径
storage = None 存储组件 默认django.core.files.storage.FileSystemStorage
ForeignKey() 外键类型在ORM中用来表示外键关联关系 一般把ForeignKey字段设置在 '一对多’中’多’的一方 ForeignKey可以和其他表做关联关系同时也可以和自身做关联关系
OneToOneField() 一对一字段 通常一对一字段用来扩展已有字段 通俗的说就是一个人的所有信息不是放在一张表里面的,简单的信息一张表,隐私的信息另一张表,之间通过一对一外键关联
ManyToManyField() 简单来说就是在多对多表关系并且这一张多对多的关系表是有Django自动帮你建的情况下 下面的方法才可使用create add set remove clear

ORM还支持用户自定义字段类型,比方说ORM中没有设置char类型的字段,我们可以使用自定义字段来实现他。

	class MyCharField(models.Field):
def __init__(self, max_length, *args, **kwargs):
self.max_length = max_length
super().__init__(max_length=max_length, *args, **kwargs) def db_type(self, connection):
return 'char(%s)' % self.max_length 这里是调用我们定义的字段类型
class User(models.Model):
name = models.CharField(max_length=32)
info = MyCharField(max_length=64)

五、ORM常用字段参数

名称 含义
primary_key 主键
verbose_name 注释
max_length 字段长度
max_digits 小数总共多少位
decimal_places 小数点后面的位数
auto_now 每次操作数据自动更新事件
auto_now_add 首次创建自动更新事件后续不自动更新
null 允许字段为空
default 字段默认值
unique 唯一值
db_index 给字段添加索引
choices 当某个字段的可能性能够被列举完全的情况下使用。如:性别、学历、工作状态、...
to 关联表
to_field 关联字段(不写默认关联数据主键)
on_delete 当删除关联表中的数据时,当前表与其关联的行的行为。

需要特别拿出来讲的是关联表时用的字段参数:

on_delete

它的值决定了关联表之前的关联操作行为

这里是代码使用展示

def func():
return 10 class MyModel(models.Model):
user = models.ForeignKey(
to="User",
to_field="id",
on_delete=models.SET(func)
)

不同的值对应的功能

1、models.CASCADE
级联操作,当主表中被连接的一条数据删除时,从表中所有与之关联的数据同时被删除
2、models.SET_NULL
当主表中的一行数据删除时,从表中所有与之关联的数据的相关字段设置为null,此时注意定义外键时,这个字段必须可以允许为空
3、models.PROTECT
当主表中的一行数据删除时,由于从表中相关字段是受保护的外键,所以都不允许删除
4、models.SET_DEFAULT
当主表中的一行数据删除时,从表中所有相关的数据的关联字段设置为默认值,此时注意定义外键时,这个外键字段应该有一个默认值
5、models.SET()
当主表中的一条数据删除时,从表中所有的关联数据字段设置为SET()中设置的值,与models.SET_DEFAULT相似,只不过此时从表中的相关字段不需要设置default参数
6、models.DO_NOTHING
什么都不做,一切都看数据库级别的约束,注数据库级别的默认约束为RESTRICT,这个约束与django中的models.PROTECT相似

choices

当字段数据的可能性是可以完全列举出来的时候 应该考虑使用该参数

		class UserInfo(models.Model):
username = models.CharField(max_length=32)
gender_choice = (
(1, '男性'),
(2, '女性'),
(3, 'other'),
)
gender = models.IntegerField(choices=gender_choice) user_obj = models.UserInfo.objects.filter(pk=1).first()
print(user_obj.gender) # 获取的是真实数据
print(user_obj.get_gender_display())
user_obj1 = models.UserInfo.objects.filter(pk=2).first()
user_obj2 = models.UserInfo.objects.filter(pk=3).first()
user_obj3 = models.UserInfo.objects.filter(pk=4).first()
print(user_obj1.get_gender_display())
print(user_obj2.get_gender_display())
print(user_obj3.get_gender_display()) # 如果没有则按照真实数据返回

六、Ajax

AJAX简介

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

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

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

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

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

ps:ajax不是一门新的技术并且有很多版本 我们目前学习的是jQuery版本(版本无所谓 本质一样就可以)

应用场景

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

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

其实这里就使用了AJAX技术!当文件框发生了输入变化时,使用AJAX技术向服务器发送一个请求,然后服务器会把查询到的结果响应给浏览器,最后再把后端返回的结果展示出来。

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

当输入用户名后,把光标移动到其他表单项上时,浏览器会使用AJAX技术向服务器发出请求,服务器会查询名为lemontree7777777的用户是否存在,最终服务器返回true表示名为lemontree7777777的用户已经存在了,浏览器在得到结果后显示“用户名已被注册!”。

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

AJAX的优点

  • AJAX使用JavaScript技术向服务器发送异步请求;
  • AJAX请求无须刷新整个页面;
  • 因为服务器响应内容不再是整个页面,而是页面中的部分内容,所以AJAX性能高;
  • 两个关键点:1.局部刷新,2.异步请求

语法实现

主体语法

	$.ajax({
url:'', // 后端地址 三种填写方式 与form标签的action一致
type:'post', // 请求方式 默认也是get
data:{'v1':v1Val, 'v2':v2Val}, // 发送的数据
success:function (args) { // 后端返回结果之后自动触发 args接收后端返回的数据
$('#d3').val(args)
}
})

jQuery发送AJAX请求示例:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1"> <style>
.hide {
display: none;
}
</style>
</head>
<body>
<p><input type="text" class="user"><span class="hide" style="color: red">用户名已存在</span></p> <script src="/static/jquery-3.3.1.min.js"></script>
{#下面这一项是基于jQuery的基础上自动给我们的每一个ajax绑定一个请求头信息,类似于form表单提交post数据必须要有的csrf_token一样#}
{#否则我的Django中间件里面的校验csrf_token那一项会认为你这个请求不是合法的,阻止你的请求#}
<script src="/static/setup_Ajax.js"></script>
<script>
//给input框绑定一个失去焦点的事件
$('.user').blur(function () {
//$.ajax为固定用法,表示启用ajax
$.ajax({
//url后面跟的是你这个ajax提交数据的路径,向谁提交,不写就是向当前路径提交
url:'',
//type为标定你这个ajax请求的方法
type:'POST',
//data后面跟的就是你提交给后端的数据
data:{'username':$(this).val()},
//success为回调函数,参数data即后端给你返回的数据
success:function (data) {
ret=JSON.parse(data);
if (ret['flag']){
$('p>span').removeClass('hide');
}
}
})
});
</script>
</body>
</html>

七、数据编码格式(Content-Type)

写在前面

在django中,针对前后端传输数据的编码格式,我们主要研究的是post请求;因为get请求传输的数据往往是直接放在url的后面的!如:

url?username=zhang&passsword=123

研究post请求传输数据的编码格式时,我们需要先了解,可以朝后端发送post请求的方式有哪些??

1.form表单中的method可以发送post请求

2.ajax中type可以指定post请求

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

1.urlencoded

2.formdata

3.json

针对能够发post请求的form表单和ajax,我们先来研究一下form表单。

form表单

form表单能够指定数据传输的编码格式只有两种,分别是默认urlencoded 和在form表单里指定enctype="multipart/form-data"的formdata格式,无法发送json格式数据

ps:

django针对contentType为urlencoded的编码格式,会自动帮你解析封装到request.POST中,所有我们才能在后端通过request.POST.get的方式进行获取前端传来的数据。

针对contenType为formdata的编码格式,前端传输过来的普通键值对还是会被封装到request.POST中,对于文件则解析封装到request.FILES中!

几种数据编码格式介绍

1.urlencoded
他是ajax默认的编码格式、form表单默认也是urlencoded
数据格式 xxx=yyy&uuu=ooo&aaa=kkk
django后端会自动处理到request.POST中 2.formdata(即multipart/form-data,具体知识点参考request对象获取文件)
django后端针对普通的键值对还是处理到request.POST中 但是针对文件会处理到request.FILES中 3.application/json
form表单不支持 ajax可以
使用ajax的时候网页返回的数据就只会被ajax接收,我们就不能设置网页跳转了。 ajax发送json格式数据
'''模拟Ajax发送数据''' html
<button id="d1">点击我发送数据</button>
<script>
$('#d1').click(function () {
$.ajax({
url:'',
type:'post',
data:JSON.stringify({'name':'Like', 'pwd':123}), // 必须json格式。传输数据的时候千万不要骗代码,代码没有这么聪明,如果我们把这里的数据值换成字典就会报错。
contentType:'application/json', // 要制定模式 默认Urlencoded
success:function (args) { }
})
})
</script> views
def ajaxjson(request):
if request.is_ajax(): # 判断当前是不是ajax请求专门的方法
if request.method == 'POST':
print(request.POST) # <QueryDict: {}>
print(request.FILES) # <MultiValueDict: {}>
'''Django后端针对json格式数据处理不了 会放在request.body里面'''
print(request.body) # b'{"name":"Like","pwd":123}'
'''Django它不会去处理需要我们自己去处理'''
json_bytes = request.body
import json
json_dict = json.loads(json_bytes) # Json解码
print(json_dict, type(json_dict))
return render(request, 'ajaxjson.html')

八、ajax携带文件数据

html
<script>
$('#d3').click(function () {
// 1.先产生一个FormData对象
let myFormDataObj = new FormData();
// 2.往该对象中添加普通数据
myFormDataObj.append('name', 'jason');
myFormDataObj.append('age', 18);
// 3.往该对象中添加文件数据
myFormDataObj.append('file', $('#d2')[0].files[0])
// 4.发送ajax请求
$.ajax({
url:'',
type:'post',
data:myFormDataObj, // ajax发送文件固定的两个配置
contentType:false,
processData:false,
success:function (args){
alert(args)
} })
})
</script> views
def ab_ajax_func(request):
if request.method == 'POST':
print(request.POST)
print(request.FILES)
这里就可以看到文件的数据了
return render(request, 'abAjaxPage.html')

九、作业

1.利用q查询进阶操作编写一个简易版本的图书查询功能
书籍名称、书籍价格...
2.利用ajax完整一个用户名实时校验功能
3.利用ajax编写一个删除功能的二次提醒

12月19日内容总结——Q查询进阶、ORM查询优化、ORM事务、ORM常用字段类型和字段参数、Ajax介绍、数据编码格式、Ajax携带文件数据的更多相关文章

  1. 22.Express框架——2019年12月19日

    2019年12月19日14:16:36 1. express简介 1.1 介绍 Express框架是后台的Node框架,所以和jQuery.zepto.yui.bootstrap都不一个东西. Exp ...

  2. 根据随身固态U盘卷标搜索U盘盘符并打开文件的批处理脚本.bat 徐晓亮 595076941@qq.com 2019年12月19日6点50分

    @Echo offRem 根据随身固态U盘卷标搜索U盘盘符并打开文件的批处理脚本.batRem 徐晓亮 595076941@qq.com 2019年12月19日6点50分 Rem 此批处理脚本源代码的 ...

  3. 2016年12月19日 星期一 --出埃及记 Exodus 21:14

    2016年12月19日 星期一 --出埃及记 Exodus 21:14 But if a man schemes and kills another man deliberately, take hi ...

  4. 北京Uber优步司机奖励政策(12月19日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  5. 24.mongodb可视化工具部署——2019年12月19日

    2019年10月09日17:05:54 教程链接:https://blog.csdn.net/qq_32340877/article/details/79142129 项目名:adminMongo g ...

  6. 31.密码学知识-证书CA/PKI-8——2019年12月19日

    1. 证书 公钥证书(Public-Key Certificate,PKC)其实和驾照很相似,里面记有姓名.组织.邮箱地址等个人信息,以及属于此人的公钥, 并由认证机构(Certification A ...

  7. 29.密码学知识-消息认证码MAC-6——2019年12月19日

    1. 消息认证码 1.1 消息认证 消息认证码(message authentication code)是一种确认完整性并进行认证的技术,取三个单词的首字母,简称为MAC. 思考改进方案? 从哈希函数 ...

  8. 28.密码学知识-hash函数-5——2019年12月19日

    5. 单向散列函数 "单向散列函数 --- 获取消息的指纹" 在刑事侦查中,侦查员会用到指纹.通过将某个特定人物的指纹与犯罪现场遗留的指纹进行对比,就能够知道该人物与案件是否存在关 ...

  9. 32.密码学知识-SSL/TLS-9——2019年12月19日

    9. SSL/TLS "SSL/TLS --- 为了更安全的通信" 本章中我们将学习SSL/TLS的相关知识. SSL/TLS是世界上应用最广泛的密码通信方法.比如说,当在网上商城 ...

  10. Week15(12月19日):授课综述2

    Part I:提问 =========================== 1.为了编辑应用程序的统一布局,可打开位于Views\Shared子目录中的(    )文件. A.MasterPage.h ...

随机推荐

  1. 这篇关于Oracle内存管理方式的介绍太棒了!我必须要转发,很全面。哈哈~

    "Oracle内存管理可分为两大类,自动内存管理和手动内存管理.其中手动内存管理又可分为自动共享内存管理,手动共享内存管理,自动PGA内存管理以及手动PGA内存管理.本文会简单的介绍不同的内 ...

  2. Python学习之实例3

    一.文字读取并打印拼接字符串 1 with open('G:\python\char.txt') as f: #使用open()函数以只读模式打开文件 2 s=f.read() #使用read()方法 ...

  3. 高性能MySQL(第4版) 第一章 MySQL架构 读书笔记

    这本书去年11月出的,今年中文版也出了,并且直接上了微信读书,之后有空就读一读,分享下读书笔记~ 原文内容比较充实,建议有时间可以读一下原文. 第一章主要是个概览. MySQL的逻辑架构 默认情况下, ...

  4. 😊SpringBoot 整合 Elasticsearch (超详细).md

    SpringBoot 整合 Elasticsearch (超详细) 注意: 1.环境搭建 安装es Elasticsearch 6.4.3 下载链接 为了方便,环境使用Windows 配置 解压后配置 ...

  5. Linux内存泄露案例分析和内存管理分享

    作者:李遵举 一.问题 近期我们运维同事接到线上LB(负载均衡)服务内存报警,运维同事反馈说LB集群有部分机器的内存使用率超过80%,有的甚至超过90%,而且内存使用率还再不停的增长.接到内存报警的消 ...

  6. shell文件报错syntax error near unexpected token '$'\r''

    本来跑的好好得一个文件,在windows下修改了,然后移植到linux就报错了. 找了一圈以下是解决方案: 这种情况发生的原因是因为你所处理的文件换行符是dos格式的"\r\n" ...

  7. NET 6 实现滑动验证码(一)、创建工程

    目录 实现滑动验证码的目的 创建.NET 6工程 实现滑动验证码的目的 传统验证码实现起来比较简单,但在OCR技术越来越成熟的情况下,验证码的破解难度越来越低,但如果将验证码难度加高(各种干扰背景,扭 ...

  8. i春秋Not Found

    点开网页,显示404,告诉我们404.php的存在,我们先试试404.php,打开是haha四个字母,源码和抓包都没看到什么,然后其抓包,也没什么,无功,返回原网页,抓包,没发现什么的感觉,go一遍, ...

  9. 关于解决linux python3安装gattlib报错

    1. 报错信息 /usr/bin/ld: cannot find -lboost_python36 collect2: error: ld returned 1 exit status error: ...

  10. 轻松玩转awk

    awk的处理方式 awk一次处理一行内容 awk对每行可以进行切片处理 例如 awk -F ':' '{print $1}' /etc/password -F指定每一行分割符号,这样就把被每行被:分割 ...