Django学习day11随堂笔记
今日考题
"""
今日考题
1.简述自定义分页器的使用
2.forms组件是干什么用的,它的主要功能有哪些功能,你能否具体说说每个功能下都有哪些经常用到的方法及注意事项(越详细越好)
3..forms组件钩子函数是干什么用的,如何编写,请举例说明,除此之外forms组件还提供了哪些校验方法
"""
内容回顾
自定义分页器的使用
"""
当你在项目中需要使用第三方的功能代码或者自己封装的一些功能代码
那么一般情况下都是会新建一个文件夹(utils)专门用来存储相关的代码
该文件夹既可以建在全局 也可以在每个应用下都创建属于该应用独有的 封装代码的思路
1.先用最粗燥的代码完成功能
2.在功能完成的基础之上再去考虑优化
1.先由面条版封装成函数
2.再看看能不能封装成面向对象
并不是说一定需要封装成面向对象的形式 要看情况
"""
# 代码无需掌握直接拷贝使用即可
# 后端使用
book_queryset = models.Book.objects.all() # 惰性查询
current_page = request.GET.get('page',1)
all_count = book_queryset.count()
page_obj = Pagenation(current_page=current_page,all_count=all_count)
page_queryset = book_queryset[page_obj.start:page_obj.end]
# 只需要将page_obj,page_queryset传递给html页面即可 # 前端使用(自定义分页器需要使用bootstrap)
{{ page_obj.page_html|safe }}
forms组件
"""
1.渲染标签
2.校验数据
3.展示信息
"""
from django import forms
class MyForm(forms.Form):
username = forms.CharField(label='用户名',max_length=8,min_length=3) # 校验数据
# 1 给类传字典
form_obj = MyForm({'username':'jason'})
# 2 判读数据是否合法
form_obj.is_valid() # 只有所有的数据都符合条件才会为True
# 3 如何查看符合条件数据
form_obj.cleaned_data
# 4 如何查看不符合条件的以及原因
form_obj.errors
# 5 forms类中所有的字段默认都是必填的
# 6 校验的数据可以多传但是不能少传 # 渲染标签
# 1 第一种
{{ form_obj.as_p }}
# 2 第二种
{{form_obj.username.label}}{{form_obj.username}}
# 3 第三种(常用)
{% for form in form_obj %}
{{ form.label }}:{{ form }}
<span>{{ form.errors.0 }}</span>
{% endfor %} # 展示错误信息
{% for form in form_obj %}
{{ form.label }}:{{ form }}
<span>{{ form.errors.0 }}</span>
{% endfor %} username = forms.CharField(label='用户名',
max_length=8,
min_length=3,
error_messages={
'required':"用户名必填",
...
} )
钩子函数
"""
局部钩子
校验单个字段
全局钩子
校验多个字段
"""
def clean_username(self):
self.add_error('username','用户名错误')
return username def clean(self):
return self.cleaned_data
重要参数
label
min_length
max_length
required
initial
error_messages
validator
widget
"""
针对字段的校验有很多种
1.最简单的min_length
2.正则validator
3.钩子函数 前端的校验的可有可无 但是后端的校验一点都不能含糊 form表单如何取消浏览器自动校验功能
<form novalidate></form>
"""
其他字段
"""
radio
checkbox
select
了解整理到博客中 之后使用再来拷贝
"""
今日内容概要
forms组件源码
cookie与session
视图函数(CBV)如何添加装饰器
forms组件源码
"""
切入点:
form_obj.is_valid()
"""
def is_valid(self):
"""
Returns True if the form has no errors. Otherwise, False. If errors are
being ignored, returns False.
"""
return self.is_bound and not self.errors
# 如果is_valid要返回True的话 那么self.is_bound要为True self.errors要为Flase
self.is_bound = data is not None or files is not None # 只要你传值了肯定为True
@property
def errors(self):
"Returns an ErrorDict for the data provided for the form"
if self._errors is None:
self.full_clean()
return self._errors
# forms组件所有的功能基本都出自于该方法
def full_clean(self):
self._clean_fields() # 校验字段 + 局部钩子
self._clean_form() # 全局钩子
self._post_clean()
cookie与session
"""
发展史
1.网站都没有保存用户功能的需求 所有用户访问返回的结果都是一样的
eg:新闻、博客、文章...
2.出现了一些需要保存用户信息的网站
eg:淘宝、支付宝、京东...
以登陆功能为例:如果不保存用户登陆状态 也就意味着用户每次访问网站都需要重复的输入用户名和密码(你觉得这样的网站你还想用吗?)
当用户第一次登陆成功之后 将用户的用户名密码返回给用户浏览器 让用户浏览器保存在本地,之后访问网站的时候浏览器自动将保存在浏览器上的用户名和密码发送给服务端,服务端获取之后自动验证
早期这种方式具有非常大的安全隐患
优化:
当用户登陆成功之后,服务端产生一个随机字符串(在服务端保存数据,用kv键值对的形式),交由客户端浏览器保存
随机字符串1:用户1相关信息
随机字符串2:用户2相关信息
随机字符串3:用户3相关信息
之后访问服务端的时候,都带着该随机字符串,服务端去数据库中比对是否有对应的随机字符串从而获取到对应的用户信息
但是如果你拿到了截获到了该随机字符串,那么你就可以冒充当前用户 其实还是有安全隐患的
你要知道在web领域没有绝对的安全也没有绝对的不安全
"""
cookie
服务端保存在客户端浏览器上的信息都可以称之为cookie
它的表现形式一般都是k:v键值对(可以有多个)
session
数据是保存在服务端的并且它的表现形式一般也是k:v键值对(可以有多个)
下述内容暂时了解即可 先给我搞明白最简单的cookie与session使用再说话!
token
session虽然数据是保存在服务端的 但是禁不住数据量大
服务端不再保存数据
登陆成功之后 将一段用户信息进行加密处理(加密算法之后你公司开发知道)
将加密之后的结果拼接在信息后面 整体返回给浏览器保存
浏览器下次访问的时候带着该信息 服务端自动切去前面一段信息再次使用自己的加密算法
跟浏览器尾部的密文进行比对
jwt认证
三段信息
(后期会讲 结合django一起使用)
总结:
1.cookie就是保存在客户端浏览器上的信息
2.session就是保存在服务端上的信息
3.session是基于cookie工作的(其实大部分的保存用户状态的操作都需要使用到cookie)
Cookie操作
# 虽然cookie是服务端告诉客户端浏览器需要保存内容
# 但是客户端浏览器可以选择拒绝保存 如果禁止了 那么 只要是需要记录用户状态的网站登陆功能都无法使用了
# 视图函数的返回值
return HttpResponse()
return render()
return redirect()
obj1 = HttpResponse()
# 在这之间操作cookie
return obj1
obj2 = render()
# 在这之间操作cookie
return obj2
obj3 = redirect()
# 在这之间操作cookie
return obj3
# 如果你想要操作cookie,你就不得不利用obj对象
"""
设置cookie
obj.set_cookie(key,value)
获取cookie
request.COOKIES.get(key)
在设置cookie的时候可以添加一个超时时间
obj.set_cookie('username', 'jason666',max_age=3,expires=3)
max_age
expires
两者都是设置超时时间的 并且都是以秒为单位
需要注意的是 针对IE浏览器需要使用expires
主动删除cookie(注销功能)
"""
"""
用户如果在没有登陆的情况下想访问一个需要登陆的页面
那么先跳转到登陆页面 当用户输入正确的用户名和密码之后
应该跳转到用户之前想要访问的页面去 而不是直接写死
"""
#校验用户是否登陆的装饰器
def login_auth(func):
def inner(request,*args,**kwargs):
# print(request.path_info)
# print(request.get_full_path()) # 能够获取到用户上一次想要访问的url
target_url = request.get_full_path()
if request.COOKIES.get('username'):
return func(request,*args,**kwargs)
else:
return redirect('/login/?next=%s'%target_url) #把target_url传递给login()
return inner
#登陆功能
def login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'kk' and password =='123':
# 获取用户上一次想要访问的url
target_url = request.GET.get('next') # 这个结果可能是None
if target_url:
obj = redirect(target_url)
else:
#保存用户登陆状态
obj = redirect('/home/')
#让浏览器记录cookie数据
obj.set_cookie('username','hahaha',max_age=3)#设置cookie超时时间3s到期
"""
浏览器不单单会帮你存
而且后面每次访问你的时候还会带着它过来
"""
#跳转到一个需要用户登陆之后才能看的页面
return obj
return render(request,'login.html')
@login_auth #此时的home变成装饰器中的func request在*args中 把request单独提出来
def home(request):
#这种方式 如果视图过多的话不太智能(也就是当用户登陆之后开放多个页面访问的时候)
#获取cookie信息,判断你有没有
# if request.COOKIES.get('username') == 'hahaha':
# return HttpResponse("我是home页面,只有登陆后的用户才能进来哦")
# #没有登陆应该跳转到登陆页面
# return redirect('/login/')
return HttpResponse("我是home页面,只有登陆后的用户才能进来哦")
@login_auth
def index(request):
return HttpResponse("我是index页面,只有登陆后的用户才能进来哦")
@login_auth
def func(request):
return HttpResponse("我是func页面,只有登陆后的用户才能进来哦")
#注销操作 只有登陆过的用户才能注销 所以也需要使用装饰器
def logout(request):
obj = redirect('/login')
obj.delete_cookie('username')
return obj
session操作
"""
session数据是保存在服务端的(存?),给客户端返回的是一个随机字符串
sessionid:随机字符串
1.在默认情况下操作session的时候需要django默认的一张django_session表
数据库迁移命令
django会自己创建很多表 django_session就是其中的一张
所以想要执行session操作需要先在项目中执行一次数据库迁移命令。确保django_session表已存在
django默认session的过期时间是14天
但是你也可以人为的修改它
设置session
request.session['key'] = value
获取session
request.session.get('key')
设置过期时间
request.session.set_expiry()
括号内可以放四种类型的参数
1.整数 多少秒
2.日期对象 到指定日期就失效
3.0 一旦当前浏览器窗口关闭立刻失效
4.不写 失效时间就取决于django内部全局session默认的失效时间(14天)
清除session
request.session.delete() # 只删服务端的 客户端的不删
request.session.flush() # 浏览器和服务端都清空(推荐使用)
session是保存在服务端的 但是session的保存位置可以有多种选择
1.MySQL
2.文件
3.redis
4.memcache
...
django_session表中的数据条数是取决于浏览器的
同一个计算机上(IP地址)同一个浏览器只会有一条数据生效
(当session过期的时候可能会出现多条数据对应一个浏览器,但是该现象不会持续很久,内部会自动识别过期的数据清除 你也可以通过代码清除)
主要是为了节省服务端数据库资源
"""
request.session['hobby'] = 'girl'
"""
内部发送了那些事
1.django内部会自动帮你生成一个随机字符串
2.django内部自动将随机字符串和对应的数据存储到django_session表中
2.1先在内存中产生操作数据的缓存
2.2在响应经过django中间件的时候才真正的操作数据库
3.将产生的随机字符串返回给客户端浏览器保存
"""
request.session.get('hobby')
"""
内部发送了那些事
1.自动从浏览器请求中获取sessionid对应的随机字符串
2.拿着该随机字符串去django_session表中查找对应的数据
3.
如果比对上了 则将对应的数据取出并以字典的形式封装到request.session中
如果比对不上 则request.session.get()返回的是None
"""
# 利用session实现登陆验证
from functools import wraps
def check_login(func):
@wraps(func)
def inner(request, *args, **kwargs):
next_url = request.get_full_path()
if request.session.get("user"):
return func(request, *args, **kwargs)
else:
return redirect("/login/?next={}".format(next_url))
return inner
def login(request):
if request.method == "POST":
user = request.POST.get("user")
pwd = request.POST.get("pwd")
if user == "alex" and pwd == "alex1234":
# 设置session
request.session["user"] = user
# 获取跳到登陆页面之前的URL
next_url = request.GET.get("next")
# 如果有,就跳转回登陆之前的URL
if next_url:
return redirect(next_url)
# 否则默认跳转到index页面
else:
return redirect("/index/")
return render(request, "login.html")
@check_login
def logout(request):
# 删除所有当前请求相关的session
request.session.delete()
return redirect("/login/")
@check_login
def index(request):
current_user = request.session.get("user", None)
return render(request, "index.html", {"user": current_user})
Session版登录验证
CBV如何添加装饰器
from django.views import View
from django.utils.decorators import method_decorator
"""
CBV中django不建议你直接给类的方法加装饰器
无论该装饰器能都正常给你 都不建议直接加
"""
# @method_decorator(login_auth,name='get') # 方式2(可以添加多个针对不同的方法加不同的装饰器)
# @method_decorator(login_auth,name='post')
class MyLogin(View):
@method_decorator(login_auth) # 方式3:它会直接作用于当前类里面的所有的方法
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request,*args,**kwargs)
# @method_decorator(login_auth) # 方式1:指名道姓
def get(self,request):
return HttpResponse("get请求")
def post(self,request):
return HttpResponse('post请求')
作业
"""
1.整理今日内容到博客
2.利用session实现登陆验证
3.复习django阶段所学所有知识点,好好整理回顾(后面没时间了)
4.预习内容:
https://www.cnblogs.com/Dominic-Ji/p/10881214.html
django中间件
auth模块
"""
Django学习day11随堂笔记的更多相关文章
- 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学习day10随堂笔记
每日测验 """ 今日考题 1.默写ajax基本语法,及提交json数据和文件都需要添加哪些额外参数 2.什么是序列化,截止目前为止你所接触过的序列化有哪些 3.批量插入 ...
- Django学习day09随堂笔记
每日测验 """ 今日考题: 1.choices参数的应用场景有哪些,如何获取该字段的值 2.django是什么模型的框架,简述MTV与MVC模型 3.多对多表关系有几种 ...
- Django学习day06随堂笔记
每日测验 """ 今日考题 1.什么是FBV与CBV,能不能试着解释一下CBV的运作原理 2.模版语法的传值需要注意什么,常见过滤器及标签有哪些 3.自定义过滤器,标签, ...
随机推荐
- JSON.stringify()的用法
**JSON.stringify() 方法用于将 JavaScript 值转换为 JSON 字符串,而我们一般只是用了第一个参数,没有在意过第二个以及第三个参数的妙用** **1.最常用的方式:** ...
- 快速从SQL语法过度到Elasticsearch的DSL语法
目录 前言 bool-相当于一个括号 should-相当于or must-相当于and must_not-相当于 ! and term-相当于= terms-相当于in between-相当于rang ...
- AbstractRoutingDataSource -- Spring提供的轻量级数据源切换方式
AbstractRoutingDataSource 只支持单库事务,也就是说切换数据源要在开启事务之前执行. spring DataSourceTransactionManager进行事务管理,开启事 ...
- 阿里云云服务器 ECS和云数据库 PolarDB的简单使用
阿里云云服务器 ECS和云数据库 PolarDB的简单使用 仅作为记录自己的操作使用,主要是怕自己太久不用都忘了 登录阿里云以后点击控制台 然后找到云服务器ECS,点击进入 在左侧找到实例,点击进入 ...
- STM32—驱动RFID-RC522模块
文章目录 一.S50(M1)卡介绍 1.S50(M1)卡基础知识 2.内部信息 3.存取控制 4.数据块的存取控制 5.控制块的存取控 6.工作原理 7.M1与读卡器的通信 二.RC522工程代码详解 ...
- SpringBoot Spring Security 核心组件 认证流程 用户权限信息获取详细讲解
前言 Spring Security 是一个安全框架, 可以简单地认为 Spring Security 是放在用户和 Spring 应用之间的一个安全屏障, 每一个 web 请求都先要经过 Sprin ...
- 题解 [JXOI2012]奇怪的道路
考场上我坚持认为这是个组合数题... 看到\(k\leq8\)我想状压来着,但是不知道怎么压 实际上,对于点i和点j的连边(\(j\in[i-k, i-1]\))只有连或不连两种状态 而如果i与比j编 ...
- 【AI】PytorchSegmentCode
From: https://liudongdong1.github.io/ 0. 基础配置 0.1. 设置随机种子 def set_seeds(seed, cuda): ""&qu ...
- zoolkeeper 的Curator的分布式锁
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3) CuratorFramework client = CuratorFram ...
- Quartz任务调度(3)存储与持久化操作配置详细解
内存存储RAMJobStore Quartz默认使用RAMJobStore,它的优点是速度.因为所有的 Scheduler 信息都保存在计算机内存中,访问这些数据随着电脑而变快.而无须访问数据库或IO ...