django的session使用,

  django的session使用,

  甜饼干

  Cookie的由来大家都知道HTTP协议是无状态的。

  无状态意味着每个请求都是独立的,它的执行和结果与前面和后面的请求没有直接关系。它不会直接受到前一个请求的响应或后一个请求的响应的影响。

  用一个有趣的词来形容,人生就像第一眼。对于服务器来说,每一个请求都是全新的。

  状态可以理解为客户端和服务器在某个会话中产生的数据,也就是说不会保留无状态的数据。会话中生成的数据就是我们需要保存的,也就是说“保持状态”。因此,Cookie就是在这样的场景下诞生的。

  什么是CookieCookie特指一小段信息。它是由服务器发送并存储在浏览器中的一组键值对。下次访问服务器时,浏览器会自动携带这些键值对,以便服务器提取有用的信息。

  Cookie的工作原理是:内容由服务器生成,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带来Cookie,让服务器通过Cookie的内容判断这是谁。

  检查Cookie我们使用Chrome浏览器,打开开发者工具。

  姜戈的曲奇行动。cookie[ key ]

  request.get _ signed _ cookie的参数(key,default=raise _ error,salt= ,max _ age=none):

  Default:默认值salt:加密salt max_age:后台控制过期时间设置Cookierep=HttpResponse(.)

  rep=render(请求,)

  rep.set_cookie(键,值,)

  Rep.set _ signed _ cookie (key,value,salt= encryption salt ,)参数:

  Key,key value=“”,value max_age=None,timeout expires=None,timeout (ie要求expires,所以如果还没有设置,就设置它。)path=/,cookie生效的路径,/表示根路径,特殊:根路径中的cookie可以被任何url访问。Domain=none,cookie生效的域名为secure=false,httpS传输为httponly=False,只能通过HTTP协议传输,JavaScript无法获取(非绝对,底层捕获可以获取或覆盖)。删除Cookiedef注销(请求):

  rep=redirect(/login/)

  Rep.delete_cookie(user) #删除用户浏览器上先前设置的usercookie值

  返回repCookie版本登录验证

  def check_login(函数):

  @wraps(func)

  def inner(request,*args,*kwargs):

  next_url=request.get_full_path()

  if request . get _ signed _ cookie( log in ,salt=SSS ,default=None)= yes :

  已经登录的用户数量.

  return func(request,*args,**kwargs)

  否则:

  #未登录的用户只需跳转到登录页面。

  返回重定向(/login/?next={} 。格式(下一个url))

  返回内部

  定义登录(请求):

  if request.method==POST :

  用户名=请求。POST.get(用户名)

  passwd=请求POST.get(密码)

  如果username==xxx 和passwd==dashabi :

  next_url=请求。GET.get(下一个)

  如果next_url和next_url!=/logout/:

  响应=重定向(下一个url)

  否则:

  response=redirect(/class _ list/)

  response . set _ signed _ cookie( log in , yes ,salt=SSS )

  返回响应

  呈现(请求, login.html) cookie版本登录

  Session Cookie的起源在一定程度上解决了“保持状态”的需要,但是由于Cookie本身最大支持4096字节,而且Cookie本身存储在客户端,可能会被截获或窃取,所以需要一种新的东西,可以支持更多的字节,它存储在服务器端,安全性高。这是会议。

  问题来了。基于HTTP协议的无状态特性,服务器根本不知道访问者是谁。那么上面的Cookie就起到了桥梁的作用。

  我们可以为每个客户端的Cookie分配一个唯一的id,这样当用户访问时,服务器将知道是谁通过Cookie访问的。然后根据不同Cookie的id,在服务器上保存一段时间的一些私密信息,比如“账号密码”等等。

  总结而言:Cookie弥补了超文本传送协议无状态的不足,让服务器知道来的人是"谁";但是饼干以文本的形式保存在本地,自身安全性较差;所以我们就通过饼干识别不同的用户,对应的在会议里保存私密的信息以及超过4096字节的文本。

  另外,上述所说的饼干和会议其实是共通性的东西,不限于语言和框架。

  姜戈中会议相关方法

  # 获取、设置、删除会议中数据

  request.session[k1]

  request.session.get(k1 ,无)

  request.session[k1]=123

  request.session.setdefault(k1 ,123) #存在则不设置

  del request.session[k1]

  # 所有键、值、键值对

  请求。会话。钥匙()

  request.session.values()

  request.session.items()

  request.session.iterkeys()

  request.session.itervalues()

  request.session.iteritems()

  # 会话会议的键

  请求。会话。会话_密钥

  # 将所有会议失效日期小于当前日期的数据删除

  request.session.clear_expired()

  # 检查会话会议的键在数据库中是否存在

  request.session.exists(会话密钥)

  # 删除当前会话的所有会议数据

  request.session.delete()

  # 删除当前的会话数据并删除会话的饼干。

  request.session.flush()

  这用于确保前面的会话数据不可以再次被用户的浏览器访问

  例如,django.contrib.auth.logout()函数中就会调用它。

  # 设置会话会议和饼干的超时时间

  请求.会话.设置_到期(值)

  * 如果价值是个整数,会话会在些秒数后失效。

  * 如果价值是个数据时间或时间增量,会话就会在这个时间后失效。

  * 如果价值是0,用户关闭浏览器会议就会失效。

  * 如果价值是无,会话会依赖全局会议失效策略。

  会议流程解析

  会议版登陆验证

  从函数工具导入包装

  定义检查_登录(函数):

  @wraps(func)

  def inner(request,*args,*kwargs):

  next_url=request.get_full_path()

  if request.session.get(user ):

  return func(request,*args,**kwargs)

  否则:

  返回重定向(/login/?next={} .格式(下一个网址))

  返回内部

  定义登录(请求):

  if request.method==POST :

  用户=请求. POST.get(用户)

  pwd=请求POST.get(pwd )

  如果用户==亚历克斯和pwd==alex1234 :

  # 设置会议

  request.session[用户]=用户

  # 获取跳到登陆页面之前的统一资源定位器

  next_url=请求. GET.get(下一个)

  # 如果有,就跳转回登陆之前的统一资源定位器

  if next_url:

  返回重定向(下一个网址)

  # 否则默认跳转到指数页面

  否则:

  返回重定向(/index/)

  返回渲染(请求,《login.html》)

  @检查_登录

  定义注销(请求):

  # 删除所有当前请求相关的会议

  request.session.delete()

  返回重定向(/login/)

  @检查_登录

  定义索引(请求):

  当前用户=请求。会话。get(用户,无)

  返回呈现(请求、 index.html 、{ 用户:当前用户})会话版登录验证

  姜戈中的会议配置姜戈中默认支持会话,其内部提供了5种类型的会议供开发者使用。

  1.数据库会议

  SESSION _ ENGINE= django。贡献。会话。后端。db #引擎(默认)

  2.缓存会议

  SESSION _ ENGINE= django。贡献。会话。后端。缓存 #引擎

  会话缓存别名=默认 #使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置

  3.文件会议

  SESSION _ ENGINE= django。贡献。会话。后端。文件 #引擎

  会话文件路径=无#缓存文件路径,如果为没有,则使用临时文件模块获取一个临时地址tempfile.gettempdir()

  4.缓存数据库

  SESSION _ ENGINE= django。贡献。会话。后端。cached _ db #引擎

  5.加密饼干会话

  SESSION _ ENGINE= django。贡献。会话。后端。签名的cookies #引擎

  其他公用设置项:

  会话饼干名称=会话id #会话的甜饼干保存在浏览器上时的钥匙,即:会话id=随机字符串(默认)

  SESSION _ COOKIE _ PATH=/ # SESSION的甜饼干保存的路径(默认)

  会话_ COOKIE _域=无#会话的甜饼干保存的域名(默认)

  SESSION_COOKIE_SECURE=False #是否安全超文本传输协议传输cookie(默认)

  SESSION_COOKIE_HTTPONLY=True #是否会议的甜饼干只支持超文本传送协议(超文本传输协议的缩写)传输(默认)

  SESSION _ COOKIE _ AGE=1209600 # SESSION的甜饼干失效日期(2周)(默认)

  SESSION _ EXPIRE _ AT _ BROWSER _ CLOSE=False #是否关闭浏览器使得会议过期(默认)

  SESSION _ SAVE _ EVERY _ REQUEST=False #是否每次请求都保存会话,默认修改之后才保存(默认)姜戈中会议相关设置

  血容量中加装饰器相关血容量实现的登录视图

  类登录视图(视图):

  定义获取(自身,请求):

  处理得到请求

  返回渲染(请求,《login.html》)

  定义发布(自己,请求):

  处理邮政请求

  用户=请求. POST.get(用户)

  pwd=请求POST.get(pwd )

  如果用户==亚历克斯和pwd==alex1234 :

  next_url=请求. GET.get(下一个)

  # 生成随机字符串

  # 写浏览器甜饼干会话id:随机字符串

  # 写到服务端会话:

  # {

  # 随机字符串:{ 用户:亚历克斯 }

  # }

  request.session[用户]=用户

  if next_url:

  返回重定向(下一个网址)

  否则:

  返回重定向(/index/)

  返回渲染(请求,《login.html》)

  要在血容量视图中使用我们上面的检查_登录装饰器,有以下三种方式:

  从姜戈。utils。装饰者导入方法_装饰者

  1.加在血容量视图的得到或邮政方法上

  从姜戈。utils。装饰者导入方法_装饰者

  班级主页视图(视图):

  定义调度(自身,请求,*参数,*kwargs):

  返回超级(HomeView,self).派遣(请求,*参数,*克沃格)

  定义获取(自身,请求):

  返回渲染(请求,《home.html》)

  @method_decorator(检查_登录)

  定义发布(自己,请求):

  打印(主页视图发布方法.)

  返回重定向(/index/)

  2.加在派遣方法上

  从姜戈。utils。装饰者导入方法_装饰者

  班级主页视图(视图):

  @method_decorator(检查_登录)

  定义调度(自身,请求,*参数,*kwargs):

  返回超级(HomeView,self).派遣(请求,*参数,*克沃格)

  定义获取(自身,请求):

  返回渲染(请求,《home.html》)

  定义发布(自己,请求):

  打印(主页视图发布方法.)

  返回重定向(/index/)

  因为血容量中首先执行的就是派遣方法,所以这么写相当于给得到和邮政方法都加上了登录校验。

  3.直接加在视图类上,但方法_装饰者必须传名字关键字参数

  如果得到方法和邮政方法都需要登录校验的话就写两个装饰器。

  从姜戈。utils。装饰者导入方法_装饰者

  @method_decorator(check_login,name=get )

  @method_decorator(check_login,name=post )

  班级主页视图(视图):

  定义调度(自身,请求,*参数,*kwargs):

  返回超级(HomeView,self).派遣(请求,*参数,*克沃格)

  定义获取(自身,请求):

  返回渲染(请求,《home.html》)

  定义发布(自己,请求):

  打印(主页视图发布方法.)

  返回重定向(/index/)

  补充跨站点请求伪造代币相关装饰器在血容量只能加到派遣方法上

  备注:

  csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便设置中没有设置全局中间件csrf_exempt,取消当前函数防跨站请求伪造功能,即便设置中设置了全局中间件。

  从django.views.decorators.csrf导入csrf_exempt,csrf_protect

  班级主页视图(视图):

  @method_decorator(csrf_exempt)

  定义调度(自身,请求,*参数,*kwargs):

  返回超级(HomeView,self).派遣(请求,*参数,*克沃格)

  定义获取(自身,请求):

  返回渲染(请求,《home.html》)

  定义发布(自己,请求):

  打印(主页视图发布方法.)

  返回重定向(/index/)

  分页自定义分页

  数据=[]

  对于范围内的一(1302):

  tmp={id: i, name: alex-{} .格式(一)}

  数据追加(tmp)

  打印(数据)

  定义用户列表(请求):

  # user_list=data[0:10]

  # user_list=data[10:20]

  尝试:

  current_page=int(请求. GET.get(page ))

  例外情况为e:

  current_page=1

  per_page=10

  # 数据总条数

  总计数=长度(数据)

  # 总页码

  total_page,more=divmod(总计数,每页)

  如果更多:

  total_page=1

  # 页面最多显示多少个页码

  max_show=11

  half_show=int((max_show-1)/2)

  如果当前页面=一半显示:

  show_start=1

  显示结束=最大显示

  否则:

  如果current _ page half _ show=total _ page:

  显示开始=总页数-最大显示

  显示结束=总页数

  否则:

  show_start=当前页面-半页显示

  show_end=当前页面半页显示

  # 数据库中获取数据

  data_start=(当前页- 1) *每页

  数据_结束=当前页*每页

  用户列表=数据[数据开始:数据结束]

  # 生成页面上显示的页码

  page_html_list=[]

  # 加首页

  first_li=阿利href=/user_list/?page=1 首页/a /li

  page_html_list.append(first_li)

  # 加上一页

  如果当前页面==1:

  prev_li=阿利href=# 上一页/a /li

  否则:

  prev_li=阿利href=/user_list/?page={} 上一页/a/李.格式(当前页面- 1)

  page_html_list.append(prev_li)

  对于范围内的我(显示开始,显示结束1):

  如果i==当前页面:

  li_tag=阿利href=/user_list/?page={ 0 }"{ 0 }/a/Li .格式(一)

  否则:

  li_tag=阿利href=/user_list/?page={ 0 }"{ 0 }/a/Li .格式(一)

  page_html_list.append(li_tag)

  # 加下一页

  如果当前页面==总页面:

  next_li=阿利href=# 下一页/a /li

  否则:

  next_li=阿利href=/user_list/?page={} 下一页/a/李.格式(当前_第一页)

  page_html_list.append(next_li)

  # 加尾页

  page_end_li=阿利href=/user_list/?page={} 尾页/a/李.格式(总页数)

  page _ html _ list。追加(page _ end _ Li)

  page_html=" " .join(page_html_list)

  返回渲染(请求、 user_list.html 、{user_list: user_list, page_html: page_html})稳扎稳打版

  类分页(对象):

  def __init__(self,current_page,total_count,base_url,per_page=10,max_show=11):

  :param current_page:当前页

  :参数总计数:数据库中数据总数

  :每页参数:每页显示多少条数据

  :param max_show:最多显示多少页

  尝试:

  当前页面=int(当前页面)

  例外情况为e:

  current_page=1

  self.current_page=当前页面

  self.total_count=总计_计数

  self.base_url=base_url

  self.per_page=per_page

  self.max_show=max_show

  # 总页码

  total_page,more=divmod(总计数,每页)

  如果更多:

  total_page=1

  half_show=int((max_show - 1)/2)

  self.half_show=half_show

  self.total_page=total_page

  @属性

  定义开始(自身):

  回归(自我。current _ page-1)* self。每页

  @属性

  定义结束(自身):

  回归自我。当前_页面*自身。每页

  def page_html(自身):

  如果自我。current _ page=自我。半_秀:

  show_start=1

  show_end=self.max_show

  否则:

  如果自我。当前_页面自我。half _ show=自我。total _ page:

  show _ start=self。total _ page-selfmax _ show

  show_end=self.total_page

  否则:

  show _ start=self。当前_页面-自己。半秀

  show _ end=自我。当前_页面自我。半秀

  # 生成页面上显示的页码

  page_html_list=[]

  # 加首页

  first_li=阿利href={}?page=1 首页/a/李.格式(self.base_url)

  page_html_list.append(first_li)

  # 加上一页

  如果self.current_page==1:

  prev_li=阿利href=# 上一页/a /li

  否则:

  prev_li=阿利href=“{ 0 }?page={1} 上一页/a/李.格式(self.base_url,self.current_page - 1)

  page_html_list.append(prev_li)

  对于范围内的我(显示开始,显示结束1):

  如果i==self.current_page:

  li_tag=阿利href=“{ 0 }?page={ 1 }"{ 1 }/a/Li .格式(self.base_url,I)

  否则:

  li_tag=阿利href=“{ 0 }?page={ 1 }"{ 1 }/a/Li .格式(self.base_url,I)

  page_html_list.append(li_tag)

  # 加下一页

  如果自我。current _ page==自身。total _ page:

  next_li=阿利href=# 下一页/a /li

  否则:

  next_li=阿利href=“{ 0 }?page={1} 下一页/a/李.格式(self.base_url,self.current_page 1)

  page_html_list.append(next_li)

  # 加尾页

  page_end_li=阿利href=“{ 0 }?page={1} 尾页/a/李.格式(self.base_url,self.total_page)

  page _ html _ list。追加(page _ end _ Li)

  返回""。join(page_html_list)封装保存版

  定义用户列表(请求):

  pager=分页(请求. GET.get(page ),len(data),request.path_info)

  user _ list=data[pager。开始:寻呼机。结束]

  page_html=pager.page_html()

  返回渲染(请求、 user_list.html 、{user_list: user_list, page_html: page_html})封装保存版使用指南

  姜戈内置分页

  从django .捷径导入渲染

  从django.core.paginator导入分页器、EmptyPage、PageNotAnInteger

  L=[]

  对于范围内的一(999):

  附加(一)

  定义索引(请求):

  当前页面=请求GET.get(p )

  paginator=Paginator(L,10)

  #每页:每页显示条目数量

  #计数:数据总个数

  #页数:总页数

  #页面范围:总页数的索引范围,如: (1,10),(1,200)

  #页面:第页对象

  尝试:

  posts=分页器。页面(当前页面)

  # has_next是否有下一页

  #下一页页码下一页页码

  #有_上一个是否有上一页

  #上一页页码上一页页码

  #对象列表分页之后的数据列表

  #编号当前页

  #分页器分页器对象

  除了PageNotAnInteger:

  posts=paginator.page(1)

  除了EmptyPage:

  posts=分页器。页面(分页器。数量_页数)

  return render(请求, index.html ,{ 帖子:帖子})内置分页视角部分

  !声明文档类型

  超文本标记语言

  头部语言

  meta charset=UTF-8

  标题/标题

  /头

  身体

  保险商实验所

  {%对于帖子中的项目%}

  李{ { item } }/李

  {% endfor %}

  /ul

  差异

  跨度

  {% if posts.has_previous %}

  a href=?p={ {帖子。上一页页码} } 上一个/a

  {% endif %}

  跨度

  第{ { posts.number } }页,共{{ posts.paginator.num_pages }}页。

  /span

  {% if posts.has_next %}

  a href=?p={{ posts.next_page_number }} 下一个/a

  {% endif %}

  /span

  /div

  /body

  /html内置分页超文本标记语言部分

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: