Django学习day10随堂笔记
每日测验
"""
今日考题
1.默写ajax基本语法,及提交json数据和文件都需要添加哪些额外参数
2.什么是序列化,截止目前为止你所接触过的序列化有哪些
3.批量插入数据需要注意什么,orm批量插入数据的语法?
4.当需要展示的数据量特别多的情况下,会采取什么优化措施,你能否简要描述一下该措施的实施思路,以及该措施具体应用下的操作步骤
5.简述面相对象的三大特性及特点,其中你认为哪个特性使用频率最高,为什么
"""
昨日内容回顾
前后端数据交互编码方式(contentType)
"""
前后端传输数据编码格式你只需要在知道下面三种即可
urlencoded formdata application/json
"""
# get请求无需研究 # 针对form表单
默认是urlencoded
数据格式:username=jason&password=123
django后端针对符合urlencoded编码格式的数据,会自动帮你解析并封装到request.POST中 form表单可以通过enctype来修改编码方式>>>:formdata
form表单即可以发送普通键值也可以发送文件
django后端针对formdata编码格式的数据,会自动将普通键值对还是解析到request.POST,将文件自动解析到request.FILES里面 form表单是无法发送json格式的数据的 # ajax
默认是urlencoded
数据格式:username=jason&password=123
django后端针对符合urlencoded编码格式的数据,会自动帮你解析并封装到request.POST中
ajax发送json格式数据
"""
不同程序/应用之间进行数据交互的时候 一定要确保数据格式和编码一致
不要欺骗别人!!!
"""
$.ajax({
url:'',
type:'',
data:JSON.stringify({'username':'jason','password':123}),
dataType:'JSON',
contentType:'application/json',
success:function(args){}
})
# 注意:django后端针对json格式的数据不会做任何的处理,你需要自己去request.body中获取原生的二进制数据自己处理
"""
1.解码
2.反序列化 (json.loads能够自动先解码再反序列化)
"""
ajax发送文件
"""
ajax发送文件需要借助于内置对象FormData 会非常的方便
"""
let formDataObj = new FormData(); # 既可以加普通键值也可以加文件
formDataObj.append('username','jason')
formDataObj.append('myfile',$('#i1')[0].files[0])
$.ajax({
url:'',
type:'',
data:formDataObj,
dataType:'JSON', # 两个关键性的参数
contentType:false,
processData:false, success:function(args){}
})
# 注意:django后端能够自动识别formdata对象 并且也能够将对象里面包含的普通键值对自己解析并封装到request.POST里面 将文件自动解析封装到request.FILES """
request对象方法补充
request.is_ajax()
"""
django内置的序列化组件
"""
到了工作中之后 大部分的项目都是前后端分离的
也就意味着我们可能无法直接使用django提供的模版语法来实现前后端数据交互 所以这个时候我们需要将数据处理成大家公共的都能处理的格式(json格式)
一般情况下都是处理成列表套字典的形式[{},{}] 由于针对数据的封装有时候会非常的繁琐 所以有现成的模块可以直接完成
1.django内置的模块
2.第三方模块:django restframework
"""
from django.core import serializers
user_queryset = models.User.objects.all()
res = serializers.serialize('json',user_queryset) # json格式字符串
return HttpResponse(res)
"""
[
{
"models":"app01.user",
"pk":1,
"fields":{
"username":"jason",
...
}
},
{},
{},
]
"""
ajax结合sweetalert实现二次确认
"""
我们在工作中写项目的时候其实也是一样的
就是先找现成的模块 代码拷贝过来然后二次修改
当你在一家公司呆了很久,那么这家的业务逻辑基本你都掌握了
"""
# sweetalert针对中文可能会出现展示不全的现象
自己找到对应的标签书写css修改样式即可 # 你也可以不结合sweetalert就用ajax和BOM操作也能完成二次确认
res = confirm()
if(res){
$.ajax({})
}else{
不发
}
批量插入
"""
当频繁的走数据库操作的时候 效率会呈现指数型下降
"""
user_list = []
for i in range(100000):
user_list.append(models.User(title='%s'%i))
models.User.objects.bulk_create(user_list)
自定义分页器
"""
django也有内置的分页器模块 但是功能较少代码繁琐不便于使用
所以我们自己自定义我们自己的分页器
"""
1.queryset对象是直接切片操作的
2.用户到底要访问哪一页 如何确定? url?page=1
current_page = request.GET.get('page',1)
# 获取到的数据都是字符串类型 你需要注意类型转换
3.自己规定每页展示多少条数据
per_page_num = 10
4.切片的起始位置和终止位置
start_page = (current_page - 1)* per_page_num
end_page = current_page * per_page_num
# 利用简单找规律 找出上述四个参数的规律
5.当前数据的总条数
book_queryset.count()
6.如何确定总共需要多少页才能展示完所有的数据
# 利用python内置函数divmod()
page_count, more = divmod(all_count,per_page_num)
if more:
page_count += 1
7.前端模版语法是没有range功能的
# 前端代码不一定非要在前端书写 也可以在后端生成传递给页面
8.针对需要展示的页码需要你自己规划好到底展示多少个页码
# 一般情况下页码的个数设计都是奇数(符合审美标准) 11个页码
当前页减5
当前页加6
你可以给标签价样式从而让选中的页码高亮显示
9.针对页码小于6的情况 你需要做处理 不能再减 自定义分页器推导到第九部就可以 无需你继续推到了 代码也无需掌握
今日内容概要
校验性组件:form组件
组件有很多很多,就类似于功能模块
# Forms组件
### 前戏
```python
"""
写一个注册功能
获取用户名和密码 利用form表单提交数据
在后端判断用户名和密码是否符合一定的条件
用户名中不能含有马思唯
密码不能少于三位
如何符合条件需要你将提示信息展示到前端页面
"""
def ab_form(request):
back_dic = {'username':'','password':''}
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if '马思唯' in username:
back_dic['username'] = '不符合社会主义核心价值观'
if len(password) < 3:
back_dic['password'] = '不能太短 不好!'
"""
无论是post请求还是get请求
页面都能够获取到字典 只不过get请求来的时候 字典值都是空的
而post请求来之后 字典可能有值
"""
return render(request,'ab_form.html',locals())
<form action="" method="post">
<p>username:
<input type="text" name="username">
<span style="color: red">{{ back_dic.username }}</span>
</p>
<p>password:
<input type="text" name="password">
<span style="color: red">{{ back_dic.password }}</span>
</p>
<input type="submit" class="btn btn-info">
</form>
"""
1.手动书写前端获取用户数据的html代码 渲染html代码
2.后端对用户数据进行校验 校验数据
3.对不符合要求的数据进行前端提示 展示提示信息
forms组件
能够完成的事情
1.渲染html代码
2.校验数据
3.展示提示信息
为什么数据校验非要去后端 不能在前端利用js直接完成呢?
数据校验前端可有可无
但是后端必须要有!!!
因为前端的校验是弱不禁风的 你可以直接修改
或者利用爬虫程序绕过前端页面直接朝后端提交数据
购物网站
选取了货物之后 会计算一个价格发送给后端 如果后端不做价格的校验
实际是获取到用户选择的所有商品的主键值
然后在后端查询出所有商品的价格 再次计算一遍
如果跟前端一致 那么完成支付如果不一致直接拒绝
"""
基本使用
from django import forms
class MyForm(forms.Form):
# username字符串类型最小3位最大8位
username = forms.CharField(min_length=3,max_length=8)
# password字符串类型最小3位最大8位
password = forms.CharField(min_length=3,max_length=8)
# email字段必须符合邮箱格式 xxx@xx.com
email = forms.EmailField()
校验数据
"""
1.测试环境的准备 可以自己拷贝代码准备
2.其实在pycharm里面已经帮你准备一个测试环境
python console (最下面终端选项旁边)
"""
#直接在校验终端里输入以下代码 进行校验
from app01 import views
# 1 将带校验的数据组织成字典的形式传入即可
form_obj = views.MyForm({'username':'jason','password':'123','email':'123'})
# 2 判断数据是否合法 注意该方法只有在所有的数据全部合法的情况下才会返回True
form_obj.is_valid()
False
# 3 查看所有校验通过的数据
form_obj.cleaned_data
{'username': 'jason', 'password': '123'}
# 4 查看所有不符合校验规则以及不符合的原因
form_obj.errors
{
'email': ['Enter a valid email address.']
}
# 5 校验数据只校验类中出现的字段 多传不影响 多传的字段直接忽略
form_obj = views.MyForm({'username':'jason','password':'123','email':'123@qq.com','hobby':'study'})
form_obj.is_valid()
True
# 6 校验数据 默认情况下 类里面所有的字段都必须传值
form_obj = views.MyForm({'username':'jason','password':'123'})
form_obj.is_valid()
False
"""
也就意味着校验数据的时候 默认情况下数据可以多传但是绝不可能少传
"""
渲染标签
"""
forms组件只会自动帮你渲染获取用户输入的标签(input select radio checkbox)
不能帮你渲染提交按钮
"""
def index(request):
# 1 先产生一个空对象
form_obj = MyForm() #这里的MyForm() 是上面校验数据时创建的
# 2 直接将该空对象传递给html页面
return render(request,'index.html',locals())
# 前端利用空对象做操作
<p>第一种渲染方式:代码书写极少,封装程度太高 不便于后续的扩展 一般情况下只在本地测试使用</p>
{{ form_obj.as_p }} p标签包裹显示
{{ form_obj.as_ul }} ul标签包裹显示
{{ form_obj.as_table }} table标签包裹显示
<p>第二种渲染方式:可扩展性很强 但是需要书写的代码太多 一般情况下不用</p>
<p>{{ form_obj.username.label }}:{{ form_obj.username }}</p>
<p>{{ form_obj.password.label }}:{{ form_obj.password }}</p>
<p>{{ form_obj.email.label }}:{{ form_obj.email }}</p>
<p>第三种渲染方式(推荐使用):代码书写简单 并且扩展性也高</p>
{% for form in form_obj %}
<p>{{ form.label }}:{{ form }}</p>
{% endfor %}
"""
label属性默认展示的是类中定义的字段首字母大写的形式
也可以自己修改 直接给字段对象加label属性即可
username = forms.CharField(min_length=3,max_length=8,label='用户名')
"""
展示提示信息
"""
浏览器会自动帮你校验数据 但是前端的校验弱不禁风
如何让浏览器不做校验
<form action="" method="post" novalidate>
"""
def index(request):
# 一.先产生一个空对象
form_obj = MyForm()
if request.method == 'POST':
# 获取用户数据并且校验
"""
1.数据获取繁琐
2.校验数据需要构造成字典的格式传入才行
ps:但是request.POST可以看成就是一个字典
"""
# 3.校验数据
form_obj = MyForm(request.POST)
# 4.判断数据是否合法
if form_obj.is_valid():
# 5.如果合法 操作数据库存储数据
return HttpResponse('OK')
# 5.不合法 有错误 将错误信息展示到前端
# 前端直接设置<span style="color: red"> {{ form.errors.0 }}</span> .0只拿到报错的第一个信息
#<form action="" method="post" novalidate> 给form表单设置novalidate 不让它校验我的表单 我的后端代码自己校验
# 二 直接将该空对象传递给html页面
return render(request, 'index.html', locals())
{% for form in form_obj %}
<p>{{ form.label }}:{{ form }}
<span style="color: red"> {{ form.errors.0 }}</span>
</p>
{% endfor %}
"""
1.必备的条件 get请求和post传给html页面对象变量名必须一样 form_obj
2.forms组件当你的数据不合法的情况下 会保存你上次的数据 让你基于之前的结果进行修改
更加的人性化
"""
# 针对错误的提示信息还可以自己自定制
class MyForm(forms.Form):
# username字符串类型最小3位最大8位
username = forms.CharField(min_length=3,max_length=8,label='用户名',
error_messages={
'min_length':'用户名最少3位',
'max_length':'用户名最大8位',
'required':"用户名不能为空"
}
)
# password字符串类型最小3位最大8位
password = forms.CharField(min_length=3,max_length=8,label='密码',
error_messages={
'min_length': '密码最少3位',
'max_length': '密码最大8位',
'required': "密码不能为空"
}
)
# email字段必须符合邮箱格式 xxx@xx.com
email = forms.EmailField(label='邮箱',
error_messages={
'invalid':'邮箱格式不正确',
'required': "邮箱不能为空"
}
)
钩子函数(HOOK)
"""
在特定的节点自动触发完成响应操作
钩子函数在forms组件中就类似于第二道关卡,能够让我们自定义校验规则
在forms组件中有两类钩子
1.局部钩子 clean_xxx
当你需要给单个字段增加校验规则的时候可以使用
2.全局钩子 clean
当你需要给多个字段增加校验规则的时候可以使用
"""
# 实际案例
# 1.校验用户名中不能含有666 只是校验username字段 局部钩子
# 2.校验密码和确认密码是否一致 password confirm两个字段 全局钩子
# 钩子函数 在类里面书写方法即可
# 局部钩子
def clean_username(self):
# 获取到用户名
username = self.cleaned_data.get('username')
if '666' in username:
# 提示前端展示错误信息
self.add_error('username', '光喊666是不行滴~')
# 将钩子函数钩去出来数据再放回去
return username #局部钩子拿什么返回什么
# 全局钩子
def clean(self):
password = self.cleaned_data.get('password')
confirm_password = self.cleaned_data.get('confirm_password')
if not confirm_password == password:
self.add_error('confirm_password', '两次密码不一致')
# 将钩子函数钩出来数据再放回去
return self.cleaned_data #全局钩子全部返回
forms组件其他参数及补充知识点
label 字段名
error_messages 自定义报错信息
initial 默认值
required 控制字段是否必填
"""
1.字段没有样式
2.针对不同类型的input如何修改
text
password
date
radio
checkbox
...
"""
widget=forms.widgets.PasswordInput(attrs={'class':'form-control c1 c2'})
# 设置当前输入框类型以及设置样式
# 多个属性值的话 直接空格隔开即可
# 第一道关卡里面还支持正则校验
validators=[
RegexValidator(r'^[0-9]+$', '请输入数字'),
RegexValidator(r'^159[0-9]+$', '数字必须以159开头')
]
其他类型渲染
# radio
gender = forms.ChoiceField(
choices=((1, "男"), (2, "女"), (3, "保密")),
label="性别",
initial=3,
widget=forms.widgets.RadioSelect()
)
# select
hobby = forms.ChoiceField(
choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
label="爱好",
initial=3,
widget=forms.widgets.Select()
)
# 多选
hobby1 = forms.MultipleChoiceField(
choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
label="爱好",
initial=[1, 3],
widget=forms.widgets.SelectMultiple()
)
# 单选checkbox
keep = forms.ChoiceField(
label="是否记住密码",
initial="checked",
widget=forms.widgets.CheckboxInput()
)
# 多选checkbox
hobby2 = forms.MultipleChoiceField(
choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
label="爱好",
initial=[1, 3],
widget=forms.widgets.CheckboxSelectMultiple()
)
作业
"""
1.整理今日内容到博客
2.利用forms组件完成用户注册完整功能
"""
Django学习day10随堂笔记的更多相关文章
- Django学习day13随堂笔记
每日测验 """ 今日考题 1.什么是django中间件,它的作用是什么,如何自定义中间件,里面有哪些用户可以自定义的方法,这些方法有何特点 2.基于django中间件的 ...
- Django学习day02随堂笔记
每日测验 """ 今日考题 1.谈谈你对web框架的认识,简述web框架请求流程 2.python三大主流web框架的区别 3.安装django需要注意的事项有哪些(最少 ...
- Django学习day12随堂笔记
每日测验 """ 1.什么是cookie和session,你能描述一下它们的由来和工作机制吗(切勿糊弄,敷衍了事) 2.django中如何操作cookie和session ...
- Django学习day08随堂笔记
今日考题 """ 今日考题 1.聚合查询,分组查询的关键字各是什么,各有什么特点或者注意事项 2.F与Q查询的功能,他们的导入语句是什么,针对Q有没有其他用法 3.列举常 ...
- Django学习day07随堂笔记
今日考题 """ 今日考题 1.必知必会N条都有哪些,每个都是干啥使的 2.简述神奇的双下划线查询都有哪些方法,作用是什么 3.针对多对多外键字段的增删改查方法有哪些,各 ...
- Django学习day05随堂笔记
每日测验 """ 今日考题 1.反向解析的本质是什么,无名和有名反向解析如何操作? 2..路由分发能够实现的前提是什么,需要注意什么,名称空间什么时候使用 3..什么是虚 ...
- Django学习day11随堂笔记
今日考题 """ 今日考题 1.简述自定义分页器的使用 2.forms组件是干什么用的,它的主要功能有哪些功能,你能否具体说说每个功能下都有哪些经常用到的方法及注意事项( ...
- Django学习day09随堂笔记
每日测验 """ 今日考题: 1.choices参数的应用场景有哪些,如何获取该字段的值 2.django是什么模型的框架,简述MTV与MVC模型 3.多对多表关系有几种 ...
- Django学习day06随堂笔记
每日测验 """ 今日考题 1.什么是FBV与CBV,能不能试着解释一下CBV的运作原理 2.模版语法的传值需要注意什么,常见过滤器及标签有哪些 3.自定义过滤器,标签, ...
随机推荐
- Linux平台上转换文件编码
Linux系统的iconv指令是一个很好的文件编码转换工具,支持的编码范围广,使用方便,例如将一个utf-8编码的文件(名为tic)转换为gbk编码: iconv -f utf-8 -t gbk ti ...
- 慕慕生鲜上线&&腾讯云服务器配置准备
1.购买服务器并配置环境 1.1 购买 618购买了腾讯云服务器三年最低配置(1核2G 1Mbps 50G云盘),一时激动忘记了购买前领优惠券,痛失25元. 1.2 环境配置 系统是 CentOS L ...
- awk-04-流程控制
if 格式: if ( 条件 ) 语句 [ else 语句 ] 单分支 正则匹配判断 双分支 多分支 while 格式 while (条件) 语句 awk是按行处理的,每次读取一行,并遍历打印每个字段 ...
- Git-05-文件删除与恢复
删除文件 1 添加一个文件test.txt文件用于测试 2 删除文件,这样删除,工作区和版本库一致 也可以直接rm 然后在 git rm,git commit 这样也能保证工作区和版本库一致 恢复误删 ...
- 基于RT1052 Aworks 内存扩容记录(一)
本文主要是通过迁移的思维,记录本人初次使用周立功的Aworks框架进行BSP开发 1. 首先阅读原理图 内存容量由32M扩容至64M. 2. 再则比较两颗芯片的参数 通过比较32M和64M SDRAM ...
- MATLAB—数组运算及数组化编程
文章目录 前言 一.数组的结构和创建 1.数组及其结构 2.行数组的创建 3.对数组构造的操作 二.数组元素编址及寻访 1.数组元素的编址 2.二维数组元素的寻访 三.数组运算 非数的问题 前言 编程 ...
- redis的五大数据类型实现原理
1.对象的类型与编码 Redis使用前面说的五大数据类型来表示键和值,每次在Redis数据库中创建一个键值对时,至少会创建两个对象,一个是键对象,一个是值对象,而Redis中的每个对象都是由 redi ...
- Java全家桶的这些知识,不用学了
众所周知,Java 的知识体系繁冗复杂,但是有很多知识在实际工作中几乎没有人用. 很多人在学习过程中,却经常把有限的时间和精力花在了这些"没有用"的知识上,事倍功半. 下面我捋一捋 ...
- 【HMC Core 6.0全球上线】图形计算服务新插件,助力高画质3D手游创新
HMS Core 6.0已于7月15日全球上线,本次新版本向广大开发者开放了众多全新能力与技术.其中华为图形计算服务(CG Kit)开放了体积雾插件和流体插件,为3D手游画面的提升提供了坚实的技术基础 ...
- [转]C# 互操作性入门系列(一):C#中互操作性介绍
传送门 C#互操作系列文章: C# 互操作性入门系列(一):C#中互操作性介绍 C# 互操作性入门系列(二):使用平台调用调用Win32 函数 C# 互操作性入门系列(三):平台调用中的数据封送处理 ...