functools <span style="color: #0000ff">def<span style="color: #000000"> check_login(func):
@wraps(func)
<span style="color: #0000ff">def inner(request,
<span style="color: #000000">kwargs):
next_url =<span style="color: #000000"> request.get_full_path()
<span style="color: #0000ff">if request.session.get(<span style="color: #800000">"<span style="color: #800000">user<span style="color: #800000">"<span style="color: #000000">):
<span style="color: #0000ff">return func(request,<span style="color: #000000">kwargs)
<span style="color: #0000ff">else<span style="color: #000000">:
<span style="color: #0000ff">return redirect(<span style="color: #800000">"<span style="color: #800000">/login/?next={}<span style="color: #800000">"<span style="color: #000000">.format(next_url))
<span style="color: #0000ff">return<span style="color: #000000"> inner
<span style="color: #0000ff">def<span style="color: #000000"> login(request):
<span style="color: #0000ff">if request.method == <span style="color: #800000">"<span style="color: #800000">POST<span style="color: #800000">"<span style="color: #000000">:
user = request.POST.get(<span style="color: #800000">"<span style="color: #800000">user<span style="color: #800000">"<span style="color: #000000">)
pwd = request.POST.get(<span style="color: #800000">"<span style="color: #800000">pwd<span style="color: #800000">"<span style="color: #000000">)
</span><span style="color: #0000ff">if</span> user == <span style="color: #800000">"</span><span style="color: #800000">alex</span><span style="color: #800000">"</span> <span style="color: #0000ff">and</span> pwd == <span style="color: #800000">"</span><span style="color: #800000">alex1234</span><span style="color: #800000">"</span><span style="color: #000000">:
</span><span style="color: #008000">#</span><span style="color: #008000"> 设置session</span>
request.session[<span style="color: #800000">"</span><span style="color: #800000">user</span><span style="color: #800000">"</span>] =<span style="color: #000000"> user
</span><span style="color: #008000">#</span><span style="color: #008000"> 获取跳到登陆页面之前的URL</span>
next_url = request.GET.get(<span style="color: #800000">"</span><span style="color: #800000">next</span><span style="color: #800000">"</span><span style="color: #000000">)
</span><span style="color: #008000">#</span><span style="color: #008000"> 如果有,就跳转回登陆之前的URL</span>
<span style="color: #0000ff">if</span><span style="color: #000000"> next_url:
</span><span style="color: #0000ff">return</span><span style="color: #000000"> redirect(next_url)
</span><span style="color: #008000">#</span><span style="color: #008000"> 否则默认跳转到index页面</span>
<span style="color: #0000ff">else</span><span style="color: #000000">:
</span><span style="color: #0000ff">return</span> redirect(<span style="color: #800000">"</span><span style="color: #800000">/index/</span><span style="color: #800000">"</span><span style="color: #000000">)
</span><span style="color: #0000ff">return</span> render(request,<span style="color: #800000">"</span><span style="color: #800000">login.html</span><span style="color: #800000">"</span><span style="color: #000000">)
@check_login
<span style="color: #0000ff">def<span style="color: #000000"> logout(request):
<span style="color: #008000">#<span style="color: #008000"> 删除所有当前请求相关的session
<span style="color: #000000"> request.session.delete()
<span style="color: #0000ff">return redirect(<span style="color: #800000">"<span style="color: #800000">/login/<span style="color: #800000">"<span style="color: #000000">)
@check_login
<span style="color: #0000ff">def<span style="color: #000000"> index(request):
current_user = request.session.get(<span style="color: #800000">"<span style="color: #800000">user<span style="color: #800000">"<span style="color: #000000">,None)
<span style="color: #0000ff">return render(request,<span style="color: #800000">"<span style="color: #800000">index.html<span style="color: #800000">",{<span style="color: #800000">"<span style="color: #800000">user<span style="color: #800000">"<span style="color: #000000">: current_user})
Session版登录验证
1
=
2<span style="color: #000000">. 缓存Session
SESSION_ENGINE
= <span style="color: #800000">'<span style="color: #800000">django.contrib.sessions.backends.cache<span style="color: #800000">' <span style="color: #008000">#<span style="color: #008000"> 引擎
SESSION_CACHE_ALIAS = <span style="color: #800000">'<span style="color: #800000">default<span style="color: #800000">' <span style="color: #008000">#<span style="color: #008000"> 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
3<span style="color: #000000">. 文件Session
SESSION_ENGINE = <span style="color: #800000">'<span style="color: #800000">django.contrib.sessions.backends.file<span style="color: #800000">' <span style="color: #008000">#<span style="color: #008000"> 引擎
SESSION_FILE_PATH = None <span style="color: #008000">#<span style="color: #008000"> 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()
- 缓存+<span style="color: #000000">数据库
SESSION_ENGINE = <span style="color: #800000">'<span style="color: #800000">django.contrib.sessions.backends.cached_db<span style="color: #800000">' <span style="color: #008000">#<span style="color: #008000"> 引擎
5<span style="color: #000000">. 加密Cookie Session
SESSION_ENGINE = <span style="color: #800000">'<span style="color: #800000">django.contrib.sessions.backends.signed_cookies<span style="color: #800000">' <span style="color: #008000">#<span style="color: #008000"> 引擎
<span style="color: #000000">
其他公用设置项:
SESSION_COOKIE_NAME = <span style="color: #800000">"<span style="color: #800000">sessionid<span style="color: #800000">" <span style="color: #008000">#<span style="color: #008000"> Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
SESSION_COOKIE_PATH = <span style="color: #800000">"<span style="color: #800000">/<span style="color: #800000">" <span style="color: #008000">#<span style="color: #008000"> Session的cookie保存的路径(默认)
SESSION_COOKIE_DOMAIN = None <span style="color: #008000">#<span style="color: #008000"> Session的cookie保存的域名(默认)
SESSION_COOKIE_SECURE = False <span style="color: #008000">#<span style="color: #008000"> 是否Https传输cookie(默认)
SESSION_COOKIE_HTTPONLY = True <span style="color: #008000">#<span style="color: #008000"> 是否Session的cookie只支持http传输(默认)
SESSION_COOKIE_AGE = 1209600 <span style="color: #008000">#<span style="color: #008000"> Session的cookie失效日期(2周)(默认)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False <span style="color: #008000">#<span style="color: #008000"> 是否关闭浏览器使得Session过期(默认)
SESSION_SAVE_EVERY_REQUEST = False <span style="color: #008000">#<span style="color: #008000"> 是否每次请求都保存Session,默认修改之后才保存(默认)
3,CBV中加装饰器
</span><span style="color: #0000ff">def</span><span style="color: #000000"> get(self,request):
</span><span style="color: #800000">"""</span><span style="color: #800000">
处理GET请求
</span><span style="color: #800000">"""</span>
<span style="color: #0000ff">return</span> render(request,<span style="color: #800000">'</span><span style="color: #800000">login.html</span><span style="color: #800000">'</span><span style="color: #000000">)
</span><span style="color: #0000ff">def</span><span style="color: #000000"> post(self,request):
</span><span style="color: #800000">"""</span><span style="color: #800000">
处理POST请求
</span><span style="color: #800000">"""</span><span style="color: #000000">
user </span>= request.POST.get(<span style="color: #800000">'</span><span style="color: #800000">user</span><span style="color: #800000">'</span><span style="color: #000000">)
pwd </span>= request.POST.get(<span style="color: #800000">'</span><span style="color: #800000">pwd</span><span style="color: #800000">'</span><span style="color: #000000">)
</span><span style="color: #0000ff">if</span> user == <span style="color: #800000">'</span><span style="color: #800000">alex</span><span style="color: #800000">'</span> <span style="color: #0000ff">and</span> pwd == <span style="color: #800000">"</span><span style="color: #800000">alex1234</span><span style="color: #800000">"</span><span style="color: #000000">:
next_url </span>= request.GET.get(<span style="color: #800000">"</span><span style="color: #800000">next</span><span style="color: #800000">"</span><span style="color: #000000">)
</span><span style="color: #008000">#</span><span style="color: #008000"> 生成随机字符串</span>
<span style="color: #008000">#</span><span style="color: #008000"> 写浏览器cookie -> session_id: 随机字符串</span>
<span style="color: #008000">#</span><span style="color: #008000"> 写到服务端session:</span>
<span style="color: #008000">#</span><span style="color: #008000"> {</span>
<span style="color: #008000">#</span><span style="color: #008000"> "随机字符串": {'user':'alex'}</span>
<span style="color: #008000">#</span><span style="color: #008000"> }</span>
request.session[<span style="color: #800000">'</span><span style="color: #800000">user</span><span style="color: #800000">'</span>] =<span style="color: #000000"> user
</span><span style="color: #0000ff">if</span><span style="color: #000000"> next_url:
</span><span style="color: #0000ff">return</span><span style="color: #000000"> redirect(next_url)
</span><span style="color: #0000ff">else</span><span style="color: #000000">:
</span><span style="color: #0000ff">return</span> redirect(<span style="color: #800000">'</span><span style="color: #800000">/index/</span><span style="color: #800000">'</span><span style="color: #000000">)
</span><span style="color: #0000ff">return</span> render(request,<span style="color: #800000">'</span><span style="color: #800000">login.html</span><span style="color: #800000">'</span>)</pre>
要在CBV视图中使用我们上面的check_login装饰器,有以下三种方式:
from django.utils.decorators import method_decorator
1. 加在CBV视图的get或post方法上
django.utils.decorators <span style="color: #0000ff">class<span style="color: #000000"> HomeView(View):
</span><span style="color: #0000ff">def</span> dispatch(self,request,**<span style="color: #000000">kwargs):
</span><span style="color: #0000ff">return</span> super(HomeView,self).dispatch(request,**<span style="color: #000000">kwargs)
</span><span style="color: #0000ff">def</span><span style="color: #000000"> get(self,request):
</span><span style="color: #0000ff">return</span> render(request,<span style="color: #800000">"</span><span style="color: #800000">home.html</span><span style="color: #800000">"</span><span style="color: #000000">)
@method_decorator(check_login)
</span><span style="color: #0000ff">def</span><span style="color: #000000"> post(self,request):
</span><span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">Home View POST method...</span><span style="color: #800000">"</span><span style="color: #000000">)
</span><span style="color: #0000ff">return</span> redirect(<span style="color: #800000">"</span><span style="color: #800000">/index/</span><span style="color: #800000">"</span>)</pre>
2. 加在dispatch方法上
django.utils.decorators <span style="color: #0000ff">class<span style="color: #000000"> HomeView(View):
@method_decorator(check_login)
</span><span style="color: #0000ff">def</span> dispatch(self,<span style="color: #800000">"</span><span style="color: #800000">home.html</span><span style="color: #800000">"</span><span style="color: #000000">)
</span><span style="color: #0000ff">def</span><span style="color: #000000"> post(self,request):
</span><span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">Home View POST method...</span><span style="color: #800000">"</span><span style="color: #000000">)
</span><span style="color: #0000ff">return</span> redirect(<span style="color: #800000">"</span><span style="color: #800000">/index/</span><span style="color: #800000">"</span>)</pre>
因为CBV中首先执行的就是dispatch方法,所以这么写相当于给get和post方法都加上了登录校验。
3. 直接加在视图类上,但method_decorator必须传 name 关键字参数
如果get方法和post方法都需要登录校验的话就写两个装饰器。
from django.utils.decorators import method_decorator
@method_decorator(check_login,name="get")
@method_decorator(check_login,name="post")
class HomeView(View):
def dispatch(self,**kwargs):
return super(HomeView,**kwargs)
def get(self,request):
return render(request,"home.html")
def post(self,request):
print("Home View POST method...")
return redirect("/index/")</pre>
4,补充
CSRF Token相关装饰器在CBV只能加到dispatch方法上
备注:
- csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
- csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
from django.views.decorators.csrf import csrf_exempt,csrf_protect
class HomeView(View):
@method_decorator(csrf_exempt)
def dispatch(self,request):
print("Home View POST method...")
return redirect("/index/")</pre>
三,分页
data =
<span style="color: #0000ff">for i <span style="color: #0000ff">in range(1,302<span style="color: #000000">):
tmp = {<span style="color: #800000">"<span style="color: #800000">id<span style="color: #800000">": i,<span style="color: #800000">"<span style="color: #800000">name<span style="color: #800000">": <span style="color: #800000">"<span style="color: #800000">alex-{}<span style="color: #800000">"<span style="color: #000000">.format(i)}
data.append(tmp)
<span style="color: #0000ff">print<span style="color: #000000">(data)
<span style="color: #0000ff">def<span style="color: #000000"> user_list(request):
</span><span style="color: #008000">#</span><span style="color: #008000"> user_list = data[0:10]</span>
<span style="color: #008000">#</span><span style="color: #008000"> user_list = data[10:20]</span>
<span style="color: #0000ff">try</span><span style="color: #000000">:
current_page </span>= int(request.GET.get(<span style="color: #800000">"</span><span style="color: #800000">page</span><span style="color: #800000">"</span><span style="color: #000000">))
</span><span style="color: #0000ff">except</span><span style="color: #000000"> Exception as e:
current_page </span>= 1<span style="color: #000000">
per_page </span>= 10
<span style="color: #008000">#</span><span style="color: #008000"> 数据总条数</span>
total_count =<span style="color: #000000"> len(data)
</span><span style="color: #008000">#</span><span style="color: #008000"> 总页码</span>
total_page,more =<span style="color: #000000"> divmod(total_count,per_page)
</span><span style="color: #0000ff">if</span><span style="color: #000000"> more:
total_page </span>+= 1
<span style="color: #008000">#</span><span style="color: #008000"> 页面最多显示多少个页码</span>
max_show = 11<span style="color: #000000">
half_show </span>= int((max_show-1)/2<span style="color: #000000">)
</span><span style="color: #0000ff">if</span> current_page <=<span style="color: #000000"> half_show:
show_start </span>= 1<span style="color: #000000">
show_end </span>=<span style="color: #000000"> max_show
</span><span style="color: #0000ff">else</span><span style="color: #000000">:
</span><span style="color: #0000ff">if</span> current_page + half_show >=<span style="color: #000000"> total_page:
show_start </span>= total_page -<span style="color: #000000"> max_show
show_end </span>=<span style="color: #000000"> total_page
</span><span style="color: #0000ff">else</span><span style="color: #000000">:
show_start </span>= current_page -<span style="color: #000000"> half_show
show_end </span>= current_page +<span style="color: #000000"> half_show
</span><span style="color: #008000">#</span><span style="color: #008000"> 数据库中获取数据</span>
data_start = (current_page - 1) *<span style="color: #000000"> per_page
data_end </span>= current_page *<span style="color: #000000"> per_page
user_list </span>=<span style="color: #000000"> data[data_start:data_end]
</span><span style="color: #008000">#</span><span style="color: #008000"> 生成页面上显示的页码</span>
page_html_list =<span style="color: #000000"> []
</span><span style="color: #008000">#</span><span style="color: #008000"> 加首页</span>
first_li = <span style="color: #800000">'</span><span style="color: #800000"><li><a href="/user_list/?page=1">首页</a></li></span><span style="color: #800000">'</span><span style="color: #000000">
page_html_list.append(first_li)
</span><span style="color: #008000">#</span><span style="color: #008000"> 加上一页</span>
<span style="color: #0000ff">if</span> current_page == 1<span style="color: #000000">:
prev_li </span>= <span style="color: #800000">'</span><span style="color: #800000"><li><a href="#">上一页</a></li></span><span style="color: #800000">'</span>
<span style="color: #0000ff">else</span><span style="color: #000000">:
prev_li </span>= <span style="color: #800000">'</span><span style="color: #800000"><li><a href="/user_list/?page={}">上一页</a></li></span><span style="color: #800000">'</span>.format(current_page - 1<span style="color: #000000">)
page_html_list.append(prev_li)
</span><span style="color: #0000ff">for</span> i <span style="color: #0000ff">in</span> range(show_start,show_end+1<span style="color: #000000">):
</span><span style="color: #0000ff">if</span> i ==<span style="color: #000000"> current_page:
li_tag </span>= <span style="color: #800000">'</span><span style="color: #800000"><li class="active"><a href="/user_list/?page={0}">{0}</a></li></span><span style="color: #800000">'</span><span style="color: #000000">.format(i)
</span><span style="color: #0000ff">else</span><span style="color: #000000">:
li_tag </span>= <span style="color: #800000">'</span><span style="color: #800000"><li><a href="/user_list/?page={0}">{0}</a></li></span><span style="color: #800000">'</span><span style="color: #000000">.format(i)
page_html_list.append(li_tag)
</span><span style="color: #008000">#</span><span style="color: #008000"> 加下一页</span>
<span style="color: #0000ff">if</span> current_page ==<span style="color: #000000"> total_page:
next_li </span>= <span style="color: #800000">'</span><span style="color: #800000"><li><a href="#">下一页</a></li></span><span style="color: #800000">'</span>
<span style="color: #0000ff">else</span><span style="color: #000000">:
next_li </span>= <span style="color: #800000">'</span><span style="color: #800000"><li><a href="/user_list/?page={}">下一页</a></li></span><span style="color: #800000">'</span>.format(current_page+1<span style="color: #000000">)
page_html_list.append(next_li)
</span><span style="color: #008000">#</span><span style="color: #008000"> 加尾页</span>
page_end_li = <span style="color: #800000">'</span><span style="color: #800000"><li><a href="/user_list/?page={}">尾页</a></li></span><span style="color: #800000">'</span><span style="color: #000000">.format(total_page)
page_html_list.append(page_end_li)
page_html </span>= <span style="color: #800000">""</span><span style="color: #000000">.join(page_html_list)
</span><span style="color: #0000ff">return</span> render(request,<span style="color: #800000">"</span><span style="color: #800000">user_list.html</span><span style="color: #800000">"</span>,{<span style="color: #800000">"</span><span style="color: #800000">user_list</span><span style="color: #800000">"</span>: user_list,<span style="color: #800000">"</span><span style="color: #800000">page_html</span><span style="color: #800000">"</span>: page_html})</pre>
(self,current_page,total_count,base_url,per_page=10,max_show=11
== 1 self.current_page </span>=<span style="color: #000000"> current_page
self.total_count </span>=<span style="color: #000000"> total_count
self.base_url </span>=<span style="color: #000000"> base_url
self.per_page </span>=<span style="color: #000000"> per_page
self.max_show </span>=<span style="color: #000000"> max_show
</span><span style="color: #008000">#</span><span style="color: #008000"> 总页码</span>
total_page,per_page)
</span><span style="color: #0000ff">if</span><span style="color: #000000"> more:
total_page </span>+= 1<span style="color: #000000">
half_show </span>= int((max_show - 1) / 2<span style="color: #000000">)
self.half_show </span>=<span style="color: #000000"> half_show
self.total_page </span>=<span style="color: #000000"> total_page
@property
</span><span style="color: #0000ff">def</span><span style="color: #000000"> start(self):
</span><span style="color: #0000ff">return</span> (self.current_page - 1) *<span style="color: #000000"> self.per_page
@property
</span><span style="color: #0000ff">def</span><span style="color: #000000"> end(self):
</span><span style="color: #0000ff">return</span> self.current_page *<span style="color: #000000"> self.per_page
</span><span style="color: #0000ff">def</span><span style="color: #000000"> page_html(self):
</span><span style="color: #0000ff">if</span> self.current_page <=<span style="color: #000000"> self.half_show:
show_start </span>= 1<span style="color: #000000">
show_end </span>=<span style="color: #000000"> self.max_show
</span><span style="color: #0000ff">else</span><span style="color: #000000">:
</span><span style="color: #0000ff">if</span> self.current_page + self.half_show >=<span style="color: #000000"> self.total_page:
show_start </span>= self.total_page -<span style="color: #000000"> self.max_show
show_end </span>=<span style="color: #000000"> self.total_page
</span><span style="color: #0000ff">else</span><span style="color: #000000">:
show_start </span>= self.current_page -<span style="color: #000000"> self.half_show
show_end </span>= self.current_page +<span style="color: #000000"> self.half_show
</span><span style="color: #008000">#</span><span style="color: #008000"> 生成页面上显示的页码</span>
page_html_list =<span style="color: #000000"> []
</span><span style="color: #008000">#</span><span style="color: #008000"> 加首页</span>
first_li = <span style="color: #800000">'</span><span style="color: #800000"><li><a href="{}?page=1">首页</a></li></span><span style="color: #800000">'</span><span style="color: #000000">.format(self.base_url)
page_html_list.append(first_li)
</span><span style="color: #008000">#</span><span style="color: #008000"> 加上一页</span>
<span style="color: #0000ff">if</span> self.current_page == 1<span style="color: #000000">:
prev_li </span>= <span style="color: #800000">'</span><span style="color: #800000"><li><a href="#">上一页</a></li></span><span style="color: #800000">'</span>
<span style="color: #0000ff">else</span><span style="color: #000000">:
prev_li </span>= <span style="color: #800000">'</span><span style="color: #800000"><li><a href="{0}?page={1}">上一页</a></li></span><span style="color: #800000">'</span>.format(self.base_url,self.current_page - 1<span style="color: #000000">)
page_html_list.append(prev_li)
</span><span style="color: #0000ff">for</span> i <span style="color: #0000ff">in</span> range(show_start,show_end + 1<span style="color: #000000">):
</span><span style="color: #0000ff">if</span> i ==<span style="color: #000000"> self.current_page:
li_tag </span>= <span style="color: #800000">'</span><span style="color: #800000"><li class="active"><a href="{0}?page={1}">{1}</a></li></span><span style="color: #800000">'</span><span style="color: #000000">.format(self.base_url,i)
</span><span style="color: #0000ff">else</span><span style="color: #000000">:
li_tag </span>= <span style="color: #800000">'</span><span style="color: #800000"><li><a href="{0}?page={1}">{1}</a></li></span><span style="color: #800000">'</span><span style="color: #000000">.format(self.base_url,i)
page_html_list.append(li_tag)
</span><span style="color: #008000">#</span><span style="color: #008000"> 加下一页</span>
<span style="color: #0000ff">if</span> self.current_page ==<span style="color: #000000"> self.total_page:
next_li </span>= <span style="color: #800000">'</span><span style="color: #800000"><li><a href="#">下一页</a></li></span><span style="color: #800000">'</span>
<span style="color: #0000ff">else</span><span style="color: #000000">:
next_li </span>= <span style="color: #800000">'</span><span style="color: #800000"><li><a href="{0}?page={1}">下一页</a></li></span><span style="color: #800000">'</span>.format(self.base_url,self.current_page + 1<span style="color: #000000">)
page_html_list.append(next_li)
</span><span style="color: #008000">#</span><span style="color: #008000"> 加尾页</span>
page_end_li = <span style="color: #800000">'</span><span style="color: #800000"><li><a href="{0}?page={1}">尾页</a></li></span><span style="color: #800000">'</span><span style="color: #000000">.format(self.base_url,self.total_page)
page_html_list.append(page_end_li)
</span><span style="color: #0000ff">return</span> <span style="color: #800000">""</span>.join(page_html_list)</pre>
使用:
def user_list(request):
pager = Pagination(request.GET.get("page"),len(data),request.path_info)
user_list = data[pager.start:pager.end]
page_html = pager.page_html()
return render(request,"user_list.html",{"user_list": user_list,"page_html": page_html})
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!