今日内容:用户登录以及分页的实现

views.py

# 登录动作
def login_action(request): # 必须继承request
if request.method == 'POST':
username = request.POST.get(username, '')
password = request.POST.get('password, '')
if username == 'admin and password == 'admin123456':
response = HttpResponseRdirect('/menssage/')
response.set_cookie('user', username, 3600) # 添加浏览器cookies
return response else:
return render(request,'index.html', {'error': '用户名或者密码错误'})

大家第一下想到的都是这样子的操作。用户登陆成功之后呢,在跳转到视图函数的过程中,通过set_cookie()的方法向浏览器中添加cookie的信息。

在这里,set_cookie()的方法在里面穿了三个参数,第一个参数user用于表示写入浏览器cookie名字,第二个参数username是由用户在登录页上输入的用户名,就是那个admin

第三个参数3600,用于设置cookie信息在浏览器里面的保存时间,默认单位为秒。

在cookie使用中虽然感觉良好,但是会存在一些安全隐患,而session相对而言就更加是安全些,那如何使用session替代cookie呢?

# 登录动作
def login_action(request): # 必须继承request
if request.method == 'POST':
username = request.POST.get(username, '')
password = request.POST.get('password, '')
if username == 'admin and password == 'admin123456':
response = HttpResponseRdirect('/menssage/')
response.set_cookie('user', username, 3600) # 添加浏览器cookies
request.session['user'] = username # 将信息记录到浏览器
return response else:
return render(request,'index.html', {'error': '用户名或者密码错误'}) def message(request):
# username = request.COOKIES.get('user', '')# 读取浏览器cookie
username = request.session.get('user', '') # 读取浏览器的session
return render(request, 'message.html', {'user', username})

在这里要注意,再次尝试登陆就会报错,为什么,因为django,还没有生成django_session表,只需要再次python manage.py migrate即可!

但是这样写出来始终很Low!

其实在django中,已经封装好了用户认证和登陆的相关办法。使用即可。

from django.contrib import auth

def login_action(request):
if request.method == 'POST':
username = request.POST.get('username', '')
password = request.POST.get('password', '')
user = auth.authenticate(username=username, password=password) # 必须要写成=的形式
if user is not None:
auth.login(request, user) # 登陆
request.session['user'] = username # 将session记录到浏览器
response = HttpResponseRedirect('/message/')
return response
else:
return render(request, 'index.html')

在使用authenticate()函数认证给出的用户名和密码,当用户名和密码都正确则返回一个user对象,否则返回为None

接下来只要在需要登陆才能访问的视图函数前面添加@login_required即可。

小细节。在urls中添加新的路径url(r'^accounts/login/$', views.index)

_____________________________________________________________________________________________

django 的分页功能:

django本身是自带分页的

django提供了Paginator的类来实现分页的功能。

from django.shortcuts import render
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger L = []
for i in range(999):
L.append(i) def index(request):
current_page = request.GET.get('p') paginator = Paginator(L, 10)
# per_page: 每页显示条目数量
# count: 数据总个数
# num_pages:总页数
# page_range:总页数的索引范围,如: (1,10),(1,200)
# page: page对象
try:
posts = paginator.page(current_page)
# has_next 是否有下一页
# next_page_number 下一页页码
# has_previous 是否有上一页
# previous_page_number 上一页页码
# object_list 分页之后的数据列表
# number 当前页
# paginator paginator对象
except PageNotAnInteger: # 防止输入不是页码
posts = paginator.page(1)
except EmptyPage: # 防止输入页码超出范围
posts = paginator.page(paginator.num_pages)
return render(request, 'index.html', {'posts': posts})

在HTML页面里

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<ul>
{% for item in posts %}
<li>{{ item }}</li>
{% endfor %}
</ul> <div class="pagination">
<span class="step-links">
{% if posts.has_previous %} # 判断是否有上一页
<a href="?p={{ posts.previous_page_number }}">Previous</a>
{% endif %}
<span class="current">
Page {{ posts.number }} of {{ posts.paginator.num_pages }}.
</span>
{% if posts.has_next %} # 判断是否有下一页
<a href="?p={{ posts.next_page_number }}">Next</a>
{% endif %}
</span> </div>
</body>
</html>

但要注意的一点是,在django中自带的分页是简单,但是也是有缺点的,当数据量相当大的时候,页面便会排满各式各样的页码图标。所以接下来,我们自己写一个分页

class Pagination(object):
"""
自定义分页
"""
def __init__(self,current_page,total_count,base_url,params,per_page_count=10,max_pager_count=11):
try:
current_page = int(current_page)
except Exception as e:
current_page = 1
if current_page <=0:
current_page = 1
self.current_page = current_page
# 数据总条数
self.total_count = total_count # 每页显示10条数据
self.per_page_count = per_page_count # 页面上应该显示的最大页码
max_page_num, div = divmod(total_count, per_page_count) # divmod(10,2),结果是(5,0);divmod(11,2),结果是(5,1)
if div:
max_page_num += 1
self.max_page_num = max_page_num # 页面上默认显示11个页码(当前页在中间)
self.max_pager_count = max_pager_count
self.half_max_pager_count = int((max_pager_count - 1) / 2) # URL前缀
self.base_url = base_url # request.GET
import copy
params = copy.deepcopy(params)
params._mutable = True
# 包含当前列表页面所有的搜索条件
# {source:[2,], status:[2], gender:[2],consultant:[1],page:[1]}
# self.params[page] = 8
# self.params.urlencode()
# source=2&status=2&gender=2&consultant=1&page=8
# href="/hosts/?source=2&status=2&gender=2&consultant=1&page=8"
# href="%s?%s" %(self.base_url,self.params.urlencode())
self.params = params @property
def start(self):
return (self.current_page - 1) * self.per_page_count @property
def end(self):
return self.current_page * self.per_page_count def page_html(self):
# 如果总页数 <= 11
if self.max_page_num <= self.max_pager_count:
pager_start = 1
pager_end = self.max_page_num
# 如果总页数 > 11
else:
# 如果当前页 <= 5
if self.current_page <= self.half_max_pager_count:
pager_start = 1
pager_end = self.max_pager_count
else:
# 当前页 + 5 > 总页码
if (self.current_page + self.half_max_pager_count) > self.max_page_num:
pager_end = self.max_page_num
pager_start = self.max_page_num - self.max_pager_count + 1 #倒这数11个
else:
pager_start = self.current_page - self.half_max_pager_count
pager_end = self.current_page + self.half_max_pager_count page_html_list = []
# {source:[2,], status:[2], gender:[2],consultant:[1],page:[1]}
# 首页
self.params['page'] = 1
first_page = '<li><a href="%s?%s">首页</a></li>' % (self.base_url,self.params.urlencode(),)
page_html_list.append(first_page) # 上一页
self.params["page"] = self.current_page - 1
if self.params["page"] < 1:
pervious_page = '<li class="disabled"><a href="%s?%s" aria-label="Previous">上一页</span></a></li>' % (
self.base_url, self.params.urlencode())
else:
pervious_page = '<li><a href = "%s?%s" aria-label = "Previous" >上一页</span></a></li>' % (
self.base_url, self.params.urlencode())
page_html_list.append(pervious_page) # 中间页码
for i in range(pager_start, pager_end + 1):
self.params['page'] = i
if i == self.current_page:
temp = '<li class="active"><a href="%s?%s">%s</a></li>' % (self.base_url,self.params.urlencode(), i,)
else:
temp = '<li><a href="%s?%s">%s</a></li>' % (self.base_url,self.params.urlencode(), i,)
page_html_list.append(temp) # 下一页
self.params["page"] = self.current_page + 1
if self.params["page"] > self.max_page_num:
self.params["page"] = self.current_page
next_page = '<li class="disabled"><a href = "%s?%s" aria-label = "Next">下一页</span></a></li >' % (
self.base_url, self.params.urlencode())
else:
next_page = '<li><a href = "%s?%s" aria-label = "Next">下一页</span></a></li>' % (
self.base_url, self.params.urlencode())
page_html_list.append(next_page) # 尾页
self.params['page'] = self.max_page_num
last_page = '<li><a href="%s?%s">尾页</a></li>' % (self.base_url, self.params.urlencode(),)
page_html_list.append(last_page) return ''.join(page_html_list)

Django的具体操作(二)的更多相关文章

  1. Python之路【第二十二篇】:Django之Model操作

    Django之Model操作   一.字段 AutoField(Field) - int自增列,必须填入参数 primary_key=True BigAutoField(AutoField) - bi ...

  2. Django之Model操作

    Django之Model操作 本节内容 字段 字段参数 元信息 多表关系及参数 ORM操作 1. 字段 字段列表 AutoField(Field) - int自增列,必须填入参数 primary_ke ...

  3. django模型系统(二)

    django模型系统(二) 常用查询 每一个django模型类,都有一个默认的管理器,objects QuerySet表示数据库中对象的列表.他可以有0到国歌过滤器.过滤器通过给定参数,缩小查询范围( ...

  4. Django之ORM操作

    Django之ORM操作 前言 Django框架功能齐全自带数据库操作功能,本文主要介绍Django的ORM框架 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计 ...

  5. Django之ORM操作(聚合 分组、F Q)

    Django之ORM操作(聚合 分组.F Q) 聚合 aggregate()是QuerySet的一个终止子句,也就是说,他返回一个包含一些键值对的字典,在它的后面不可以再进行点(.)操作.   键的名 ...

  6. Django 2.0 学习(16):Django ORM 数据库操作(下)

    Django ORM数据库操作(下) 一.增加表记录 对于表单有两种方式: # 方式一:实例化对象就是一条表记录france_obj = models.Student(name="海地&qu ...

  7. Django 2.0 学习(14):Django ORM 数据库操作(上)

    Django ORM 数据库操作(上) ORM介绍 映射关系: 数据库表名 ---------->类名:数据库字段 ---------->类属性:数据库表一行数据 ----------&g ...

  8. Django ORM models操作

    title: Django ORM models操作 tags: Django --- Django ORM models操作 Django ORM基本操作 一.数据库的创建及增删改查 1 使用类创建 ...

  9. Django之学员管理二

    Django之学员管理二 学生表的一对多的增删改查 views.py def students(request): #select students.sid,students.name,classes ...

  10. 【Django】ORM操作#2

    目录 必知必会的13条查询方法 单表查询之神奇的双下划线 一对多 ForeignKey 多对多 ManyToManyField 在Python脚本中调用Django环境 Django终端打印SQL语句 ...

随机推荐

  1. 03_JSX理解和使用

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. hadoop-2

    AsyncDispatcher,直接看代码 @Override protected void serviceStart() throws Exception { //start all the com ...

  3. spark Kryo serialization failed: Buffer overflow 错误

    今天在写spark任务的时候遇到这么一个错误,我的spark版本是1.5.1. Exception in thread "main" com.esotericsoftware.kr ...

  4. 剑指offer例题——旋转数组的最小数字

    题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转, ...

  5. linux thread_info 与thread_struct

    有个同事看3.10代码中,看着两个结构,会混淆,所以我简单答复了一下. thread_info是和内核栈放一块的,网上到处都是thread_info的资料,但thread_struct的资料比较少,在 ...

  6. 第五次Scrum冲刺

    第五次Scrum冲刺 1.成员今日完成情况 队员 今日完成任务 刘佳 前端初步构建 李佳 后端设计初级阶段 周世元 数据设计 杨小妮 博客编写 许燕婷 管理团队当日及次日任务 陈水莲 测试矩阵用例设计 ...

  7. IDEA 中的一些概念变化

    IntelliJ系中的Project相当于Eclipse系中的workspace. IntelliJ系中的Module相当于Eclipse系中的Project. idea中只能配置一个maven,而且 ...

  8. ArcGIS案例学习笔记3_1_地理配准案例_目视找点

    ArcGIS案例学习笔记3_1_地理配准案例_目视找点 计划时间:第3天上午 方法:地理配准/添加链接点/左键/右键/输入坐标 数据:江苏省.zip 矢量:省界,市界,GPS WGS84 地理坐标系 ...

  9. Kubernetes1.9 二进制版集群+ipvs+coredns

    节点构造如下 : 节点ip 节点角色 hostname 192.168.0.57 node bigdata3       192.168.0.56 node bigdata4       192.16 ...

  10. @Component单例与并发(未解决)

    今天用websocket记录连接的个数: 模拟少量请求到服务器端的websocket,@Component默认是单例的,让其注解到MyWebSocket类上: 每次请求过来都是相同的MyWebSock ...