分页器,cookie,session ,中间件
推导分页的原理(你只需要明白原理即可,代码不需掌握)
# 分页:当数据量过多的时候,一页展示不完,我们分好多页来展示
几个参数:
1. 当前第几页
2. 总数据量有多少(从数据库中查询出来)
3. 每页展示20条(自己规定的)
4. 总数据量 / 每页展示的条数 = 总页数
# 把数据每页展示10条
展示多少也如何计算?
"""
总数据量 每页展示的数据 总页数
100 10 10
101 10 11
99 10 10
divmod(100, 10)
"""
# book_list支持切片
# book_list = models.Book.objects.all()[0:10] # 第一页的数据
# book_list = models.Book.objects.all()[10:20] # 第二页的数据
book_queryset = models.Book.objects.all()
# 总数量
all_count = book_queryset.count()
# 每页展示多少条数据
per_page_num = 10
# 我让你查看第10页的数据
# 我们要知道当前是第几页
current_page = request.GET.get('page', 1) # 当接收不到当前页码的时候,就默认是第一页
current_page = int(current_page)
print(current_page)
start = (current_page - 1) * per_page_num
end = current_page * per_page_num
# 计算出总共多少页
page_count, yushu = divmod(all_count, per_page_num)
if yushu:
page_count += 1 # 10
page_html = ''
# for i in range(1, page_count+1):
xxx = current_page
if current_page<6:
current_page = 6
for i in range(current_page-5, current_page+6):
if i == xxx:
page_html += '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i)
else:
page_html += '<li ><a href="?page=%s">%s</a></li>' % (i, i)
book_list = book_queryset[start:end] # 第三页的数据
return render(request, 'index.html', locals())
自定义分页器的使用
django自带分页器模块但是使用起来很麻烦 所以我们自己封装了一个
# 以后再实际项目中,会经常用到非django 的第三方工具,对于这种第三方工具,我们一般会在django中新建一个文件夹叫 utils,以后很多封装的代码都使用用面向对象的写法
只需要掌握使用方式即可
view界面
from utils.mypage import Pagination
def ab_pg_func(request):
book_queryset = models.Books01.objects.all()
from app01.utils.mypage import Pagination
current_page = request.GET.get('page')
page_obj = Pagination(current_page=current_page, all_count=book_queryset.count())
page_queryset = book_queryset[page_obj.start:page_obj.end]
return render(request, 'pgPage.html', locals())
html界面
{% for book_obj in page_queryset %}
<p>{{ book_obj.title }}</p>
{% endfor %}
{{ page_obj.page_html|safe }}
django操作cookie
编写一个真正的用户登录功能
登录校验:
def login_func(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'jason' and password == '123':
obj = redirect('/home/')
obj.set_cookie('name', username)
return obj
return render(request, 'loginPage.html')
登录装饰器:
def login_auth(func_name):
def inner(request, *args, **kwargs):
if request.COOKIES.get('name'):
res = func_name(request, *args, **kwargs)
return res
return redirect('/login/')
return inner
@login_auth
def home_func(request):
return HttpResponse('home页面 只有登录的用户才可以查看')
进阶操作:用户没有登录之前想访问某个网站输入用户名密码之后就应该调回该网站而不是主页
def login_func(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'jason' and password == '123':
#拿到next的值为home1
target_path = request.GET.get('next')
if target_path:#判断target_path存不存在,不存在则返回自定义的主界面
obj = redirect(target_path)
else:
obj = redirect('/home/')
obj.set_cookie('name', username)
return obj
return render(request, 'loginPage.html')
def login_auth(func_name):
def inner(request, *args, **kwargs):
# print(request.path) # 只获取用户输入的路由信息
# print(request.path_info) # 只获取用户输入的路由信息
target_path = request.path_info
# print(request.get_full_path()) # 获取用户输入的路由信息+问号后面携带的数据
if request.COOKIES.get('name'):
res = func_name(request, *args, **kwargs)
return res
return redirect('/login/?next=%s' % target_path)
#http://127.0.0.1:8000/login/?next=/home1/
return inner
@login_auth
def home_func(request):
return HttpResponse('欢迎来到home界面')
@login_auth
def home1_func(request):
return HttpResponse('欢迎来到home1界面')
django操作session
由于session是保存在服务端上面的数据 就应该有个地方能够存储
我们只需要执行数据库迁移命令即可 django会自动创建很多需要的表
django默认的session失效时间是14天
设置session
request.session['key'] = value
1.生成一个随机字符串
2.对value数据做加密处理 并在django_session表中存储
随机字符串>>>加密数据
3.将随机字符串也发送一份给客户端保存(cookie)
sessionid:随机字符串
获取session
request.session.get('key')
1.自动获取随机字符串
2.去django_session表中根据随机字符串获取加密的数据
3.自动解密数据并处理到request.sesion.get()中
补充说明
1.可以设置过期时间
resquest.session.set_expiry(秒)
2.存储session数据的位置也可以修改
django中间件
django默认有七个中间件 并且还支持用户自定义中间件
中间件主要可以用于:网站访问频率的校验 用户权限的校验等全局类型的功能需求
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
如何自定义中间件
1.创建存储自定义中间件代码的py文件或者目录(如果中间件很多)
mymiddleware ---> mumiddle.py
2.参考自带中间件的代码编写类并继承
class MyMiddLeware001(MiddlewareMixin):
def process_request(self,request):
print('from MyMiddLeware001 process_request')
def process_response(self,request,response):
print('from MyMiddLeware001 process_response')
return response
3.在类中编写五个可以自定义的方法
需要掌握的
process_request
1.请求来的时候会从上往下依次经过每一个注册了的中间件里面的该方法 如果没有则直接跳过
2.如果该方法自己返回了HttpResponse对象那么不再往后执行而是直接原路返回
process_response
1.响应走的时候会从下往上依次经过每一个注册了的中间件里面的该方法 如果没有则直接跳过
2.该方法有两个形参request和response 形参response指代的就是后端想要返回给前端浏览器的数据 该方法必须返回该形参 也可以替换
'''如果在执行process_request方法的时候直接返回了HttpResponse对象那么会原路返回执行process_response 不是执行所有'''
需要了解的
process_view
process_exception
process_template_response
4.一定在配置文件中注册中间件才可以生效
# 但是,在flask框架中,如果你在第一个拦截了,后面的类似于是process_response都会走一遍.
'''flask框架中实际上没有真正的中间件,它是需要你看源码自己做成类似于django的这种中间件'''
django中间件三个了解的方法
1.process_view
路由匹配成功之后执行视图函数/类之前自动触发(顺序同process_request)
2.process_exception
视图函数/类执行报错自动触发(顺序同process_response)
3.process_template_response
视图函数/类返回的HttpResponse对象含有render并且对应一个方法的时候自动触发(顺序同process_response)