首页 > 代码库 > web前端基础知识 - Django进阶
web前端基础知识 - Django进阶
1. 路由系统
1.1 单一路由对应
url(r‘^index$‘, views.index),
1.2 基于正则的路由
url(r‘^index/(\d*)‘, views.index), url(r‘^manage/(?P<name>\w*)/(?P<id>\d*)‘, views.manage),
- 找到urls.py文件,修改路由规则
from django.conf.urls import url,include from django.contrib import admin from cmdb import views urlpatterns = [ url(r‘^index‘, views.index), url(r‘^detail-(\d+).html/‘, views.detail), ]
- 在views.py文件创建对应方法
USER_DICT = { ‘1‘:{‘name‘:‘root1‘,‘email‘:‘root@live.com‘}, ‘2‘:{‘name‘:‘root2‘,‘email‘:‘root@live.com‘}, ‘3‘:{‘name‘:‘root3‘,‘email‘:‘root@live.com‘}, ‘4‘:{‘name‘:‘root4‘,‘email‘:‘root@live.com‘}, } def index(request): return render(request,"index.html",{"user_dict":USER_DICT}) def detail(request,nid): # nid指定的是(\d+)里的内容 detail_info = USER_DICT[nid] return render(request, "detail.html", {"detail_info": detail_info})
1.3 url分组
在url.py增加对应路径
from django.conf.urls import url,include from django.contrib import admin from cmdb import views urlpatterns = [ url(r‘^index‘, views.index), url(r‘^detail-(?P<nid>\d+)-(?P<uid>\d+).html/‘, views.detail),<br> # nid=\d+ uid=\d+ ]
在views.py文件创建对应方法
def detail(request,**kwargs): print(kwargs) #{‘nid‘: ‘4‘, ‘uid‘: ‘3‘} nid = kwargs.get("nid") detail_info = USER_DICT[nid] return render(request, "detail.html", {"detail_info": detail_info})
1.4 为路由映射名称
from django.conf.urls import url,include from django.contrib import admin from cmdb import views urlpatterns = [ url(r‘^asdfasdfasdf/‘, views.index, name=‘i1‘), #第一种方式i1 url(r‘^yug/(\d+)/(\d+)/‘, views.index, name=‘i2‘), #第二种方式i2 url(r‘^buy/(?P<pid>\d+)/(?P<nid>\d+)/‘, views.index, name=‘i3‘), #第三种方式i3
在templates目录下的index.html
<body> {#第一种方法i1 路径asdfasdfasdf/#} {#<form action="{% url "i1" %}" method="post">#} {#第二种方法i2 路径yug/1/2/#} {#<form action="{% url "i2" 1 2 %}" method="post">#} {#第三种方法i3 路径buy/1/9//#} <form action="{% url "i3" pid=1 nid=9 %}" method="post"> <p><input name="user" type="text" placeholder="用户名"/></p> <p><input name="password" type="password" placeholder="密码"/></p> <p><input type="submit" value="http://www.mamicode.com/提交"/></p> </form> </body>
1.5 根据app对路由分类
主程序urls.py文件
from django.conf.urls import url,include from django.contrib import admin urlpatterns = [ url(r‘^monitor/‘, include(‘monitor.urls‘)), #调整到monitor目录中的urls.py文件 ]
cmdb下的url.py文件
from django.conf.urls import url from django.contrib import admin from monitor import views # urlpatterns = [ url(r‘^login‘, views.login), ]
1.6 获取当前URL
view.py中配置
def index(request): print(request.path_info) #获取客户端当前的访问链接 # / index return render(request,"index.html",{"user_dict":USER_DICT})
在templates目录下的index.html文件
<form action="{{ request.path_info }}" method="post"> <p><input name="user" type="text" placeholder="用户名"/></p> <p><input name="password" type="password" placeholder="密码"/></p> <p><input type="submit" value="http://www.mamicode.com/提交"/></p> </form>
1.7 默认值
在url.py增加对应路径
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r‘^index/‘,views.index,{"name":"root"}), ]
在views.py文件创建对应方法
from django.shortcuts import render,HttpResponse def index(request,name): return HttpResponse("%s is ok"%name)
运行并访问http://127.0.0.1:8000/index,页面显示:root is ok
1.8 命名空间
不同的url指向同一个视图就需要借助命名空间
主程序url.py文件
from django.conf.urls import url,include urlpatterns = [ url(r‘^a/‘, include(‘app01.urls‘, namespace=‘author-polls‘)), url(r‘^b/‘, include(‘app01.urls‘, namespace=‘publisher-polls‘)), ]
app01下的urls.py文件
from django.conf.urls import url from app01 import views app_name = ‘app01‘ urlpatterns = [ url(r‘^index/$‘, views.detail, name=‘detail‘) ]
在views.py文件创建对应方法
from django.shortcuts import render,HttpResponse def index(request): return HttpResponse("ok")
访问http://127.0.0.1:8000/a/index,页面显示"ok"
以上定义带命名空间的url之后,使用name生成URL时候,应该如下:
- v = reverse(‘author-polls:detail‘)
- {% url ‘author-polls:detail‘%}
2. 视图
2.1 获取用户请求数据
request.GET
request.POST
request.FILES
其中,GET一般用于获取/查询 资源信息,而POST一般用于更新 资源信息 ; FILES用来获取上传文件;
2.2 checkbox等多选的内容
在templates目录下创建login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/login" method="POST" > <p> 男:<input type="checkbox" name="favor" value="http://www.mamicode.com/11"/> 女:<input type="checkbox" name="favor" value="http://www.mamicode.com/22"/> 人妖:<input type="checkbox" name="favor" value="http://www.mamicode.com/33"/> </p> <input type="submit" value="http://www.mamicode.com/提交"/> </form> </body> </html>
修改views.py文件对表单处理
def login(request): #checkbox 多选框 if request.method == "POST": favor_list = request.POST.getlist("favor") #getlist获取多个值 print(favor_list) #多选框获取到的是列表格式 #[‘11‘, ‘22‘, ‘33‘] return render(request,"login.html") elif request.method == "GET": return render(request,"login.html") else: print("other")
2.3 上传文件
文件对象 = reqeust.FILES.get() 文件对象.name 文件对象.size 文件对象.chunks()
在templates目录下创建login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/login" method="POST" enctype="multipart/form-data"> <p> <input type="file" name="files"/> </p> <input type="submit" value="http://www.mamicode.com/提交"/> </form> </body> </html>
修改views.py文件对表单处理
def login(request): #file 上传文件 if request.method == "POST": obj = request.FILES.get(‘files‘) #用files获取文件对象 if obj: print(obj, type(obj), obj.name) # test.jpg <class ‘django.core.files.uploadedfile.InMemoryUploadedFile‘> test.jpg import os file_path = os.path.join(‘upload‘, obj.name) f = open(file_path, "wb") for item in obj.chunks(): #chunks表示所有的数据块,是个迭代器 f.write(item) f.close() return render(request,"login.html") elif request.method == "GET": return render(request,"login.html") else: print("other")
2.4 请求的其他信息
from django.core.handlers.wsgi import WSGIRequest request.environ #获取所有用户请求信息 request.environ[‘HTTP_USER_AGENT‘] #获取用户请求的设备信息
2.5 FBV & CBV
2.5.1 FBV
1.在templates目录下创建home.html文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/home/" method="POST"> <p> <input type="text" name="user" placeholder="用户名"/> </p> <p> <input type="password" name="pwd" placeholder="密码"/> </p> <p> <input type="submit" value="http://www.mamicode.com/提交"> </p> </form> </body> </html>
2. 在urls.py文件增加home路径
from django.conf.urls import url,include from django.contrib import admin from cmdb import views urlpatterns = [ # 固定语法 url(r‘^home/‘, views.Home.as_view()), ]
3. 在views.py文件创建函数Home
def home(request): return render(request,"home.html")
2.5.2 CBV
1. 在templates目录下创建home.html文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/home/" method="POST"> <p> <input type="text" name="user" placeholder="用户名"/> </p> <p> <input type="password" name="pwd" placeholder="密码"/> </p> <p> <input type="submit" value="http://www.mamicode.com/提交"> </p> </form> </body> </html>
2. 在urls.py文件增加home路径
from django.conf.urls import url,include from django.contrib import admin from cmdb import views urlpatterns = [ # 固定语法 url(r‘^home/‘, views.Home.as_view()), ]
3. 在views.py文件创建类Home
from django.views import View class Home(View): # 先执行dispatch里面的内容 def dispatch(self,request, *args, **kwargs): print("before") # 调用父类中的dispatch result = super(Home,self).dispatch(request, *args, **kwargs) print("after") return result # 根据反射获取用户提交方式,执行get或post方法 def get(self,request): print(request.method) return render(request,"home.html") def post(self,request): print(request.method) return render(request,"home.html")
3. Templates
通过之前的学习我们已经可以实现模板功能,但是大家会发现一个问题:按照之前学习的方法,同一个系统下的不同功能页面,我们需要在每个页面复制菜单、左侧右侧导航等;这样虽然也可以实现我们的需求,但是如果菜单、左右侧导航有所修改,我们就需要再挨个去变更。那么有没有其他的方法解决这个问题呢?----这里我们引入母版。
3.1 继承
首先,我们需要新建一个母版html文件(如:master.html),文件内容如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{% block title %}{% endblock %}</title> <style> .pg_header{ height: 50px; background-color: aquamarine; color:green; } </style> </head> <body> <div class="pg_header">母版测试</div> {% block content %}{% endblock %} </body> </html>
再新建一个子板html文件(如:userlist.html),文件内容如下:
{% extends ‘master.html‘ %} <!--有多个母版时,此处可区分继承的是哪个母版--> {% block title %}用户管理{% endblock %} {% block content %} <h1>用户管理</h1> <ul> {% for i in u %} <li>{{ i }}</li> {% endfor %} </ul> {% endblock %}
运行后查看页面,userlist.html继承了母版master.html的CSS和JS。(想要修改导航、菜单等内容,直接修改母版内容即可。)
学习完上面的东西之后,大家很快就会发现另外一个问题:上面的东西虽然能实现我们的需求,但是每个页面想要使用自己的CSS和JS就不行了,如何解决这个问题呢?
1.母版文件内容
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{% block title %}{% endblock %}</title> <style> .pg_header{ height: 50px; background-color: aquamarine; color:green; } </style> {% block css %}{%endblock%} </head> <body> <div class="pg_header">母版测试</div> {% block content %}{% endblock %} <script src="http://www.mamicode.com/XXX"></script> {% block js %}{%endblock%} </body> </html>
2. 子板文件内容
{% extends ‘master.html‘ %} <!--有多个母版时,此处可区分继承的是哪个母版--> {% block title %}用户管理{% endblock %} {% block content %} <h1>用户管理</h1> <ul> {% for i in u %} <li>{{ i }}</li> {% endfor %} </ul> {% endblock %} {% block css%} <style> .body{ color:red } </style> {% endblock%} {% block js%} <script>.....</script> {% endblock%}
PS:一个html文件只能继承一个母版
3.2 导入
新建tag.html文件, 文件内容如下:
<form> <input type="text"/> <input type="submit"/> </form>
子板文件中插入代码
<% include "tag.html" %> <% include "tag.html" %> <% include "tag.html" %> <% include "tag.html" %>
3.3 自定义simple_tag
-
在app中创建templatetags模块
- 创建任意 .py 文件,如:xx.py
#!/usr/bin/env python #coding:utf-8 from django import template from django.utils.safestring import mark_safe register = template.Library() @register.simple_tag def my_simple_time(v1,v2,v3): return v1 + v2 + v3 @register.simple_tag def my_input(id,arg): result = "<input type=‘text‘ id=‘%s‘ class=‘%s‘ />" %(id,arg,) return mark_safe(result)
3. 在使用自定义simple_tag的html文件顶部导入之前创建的 xx.py 文件名
{% load xx %}
4. 使用simple_tag
{% 函数名 arg1 arg2 %} {% my_simple_time 1 2 3%} {% my_input ‘id_username‘ ‘hide‘%}
5. 在settings中配置当前app,不然django无法找到自定义的simple_tag
INSTALLED_APPS = ( ‘django.contrib.admin‘, ‘django.contrib.auth‘, ‘django.contrib.contenttypes‘, ‘django.contrib.sessions‘, ‘django.contrib.messages‘, ‘django.contrib.staticfiles‘, ‘app01‘, )
3.4 自定义filter
-
在app中创建templatetags模块
-
创建任意 .py 文件,如:xx.py
#!/usr/bin/env python #coding:utf-8 from django import template from django.utils.safestring import mark_safe register = template.Library() @register.filter def my_simple_time(v1,v2): return v1 + v2 @register.filter def my_input(id,arg): result = "<input type=‘text‘ id=‘%s‘ class=‘%s‘ />" %(id,arg,) return mark_safe(result)
3. 在使用自定义filter的html文件顶部导入之前创建的 xx.py 文件名
{% load xx %}
4. 使用filter
{{ 参数1|函数名:"参数二,参数三" }} {{ 参数1|函数名:数字 }}
5. 在settings中配置当前app,不然django无法找到自定义的simple_tag
INSTALLED_APPS = ( ‘django.contrib.admin‘, ‘django.contrib.auth‘, ‘django.contrib.contenttypes‘, ‘django.contrib.sessions‘, ‘django.contrib.messages‘, ‘django.contrib.staticfiles‘, ‘app01‘, )
filter和simple_tag的优缺点:
- simple_tag不能作为if条件;但可使用任意参数;
- filter可以作为if条件;但最多两个参数,不能加空格;
4. 分页
4.1 django内置分页
Paginator
4.2 自定义分页
分页功能在每个网站都是必要的,对于分页来说,其实就是根据用户的输入计算出应该在数据库表中的起始位置。
4.2.1 准备基础数据
1. 在url.py增加对应路径
from django.conf.urls import url,include from django.contrib import admin from cmdb import views urlpatterns = [ url(r‘^index‘, views.index), url(r‘^userlist/‘, views.userlist), ]
2. 在views.py文件创建对应方法
from django.shortcuts import render,HttpResponse LIST=[] for i in range(109): LIST.append(i) def user_list(request): return render(request,‘userlist.html‘,{‘li‘:LIST})
3. 在templates目录下的userlist.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <ul> {% for item in li %} <li>{{ item }}</li> {% endfor %} </ul> </body> </html>
运行程序并访问http://127.0.0.1:8000/userlist/,我们会发现该页面直接显示所有数据;
4.2.2 实现简单分页
我们可以考虑在url后带上参数表名用户访问的是第几页,从而返回数据;
views.py文件更改:
def userlist(request): current_page = request.GET.get(‘p‘,1) current_page = int(current_page) start = (current_page-1)*10 end = current_page*10 data = http://www.mamicode.com/LIST[start:end]>
重新运行程序后访问http://127.0.0.1:8000/userlist/?p=2,我们就可以看到第二页的数据了
4.2.3 简单优化
上面虽然可以实现简单分页,但是考虑到用户体验,肯定不能让用户如此访问,我们需要简单优化下:
html文件更改:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <ul> {% for item in li %} <li>{{ item }}</li> {% endfor %} </ul> <div> <a href="http://www.mamicode.com/user_list/?p=1">1</a> <a href="http://www.mamicode.com/user_list/?p=2">2</a> <a href="http://www.mamicode.com/user_list/?p=3">3</a> </div> </body> </html>
重新运行程序后访问http://127.0.0.1:8000/userlist/,点击页面的1、2即可实现简单翻页功能;
4.2.4 最终分页实现
现在新的分页需求下来了:
1)每页10条;
2)停留在第一页的时候,上一页不可点击;停留在末页的时候,下一页不可点击;
3)当前页面被默认选中且颜色高亮显示;
4)只显示当前页、前3个页码和后3个页码;
头疼Ing,继续苦逼的写代码吧!
app的同级目录下新建utils目录,目录下新建pagination.py文件,文件内容如下:
1 from django.utils.safestring import mark_safe 2 class Page: 3 def __init__(self,current_page,data_count,per_page_count=10,pager_num=7): 4 self.current_page = current_page 5 self.data_count = data_count 6 self.per_page_count = per_page_count 7 self.pager_num = pager_num 8 @property 9 def start(self): 10 return (self.current_page-1) * self.per_page_count 11 @property 12 def end(self): 13 return self.current_page * self.per_page_count 14 @property 15 def total_count(self): 16 v,y = divmod(self.data_count, self.per_page_count) 17 if y: 18 v += 1 19 return v 20 def page_str(self, base_url): 21 page_list = [] 22 if self.total_count < self.pager_num: 23 start_index = 1 24 end_index = self.total_count + 1 25 else: 26 if self.current_page <= (self.pager_num+1)/2: 27 start_index = 1 28 end_index = self.pager_num + 1 29 else: 30 start_index = self.current_page - (self.pager_num-1)/2 31 end_index = self.current_page + (self.pager_num+1)/2 32 if (self.current_page + (self.pager_num-1)/2) > self.total_count: 33 end_index = self.total_count + 1 34 start_index = self.total_count - self.pager_num + 1 35 if self.current_page == 1: 36 prev = ‘<a class="page" href="javascript:void(0);">上一页</a>‘ 37 else: 38 prev = ‘<a class="page" href="http://www.mamicode.com/%s?p=%s">上一页</a>‘ %(base_url,self.current_page-1,) 39 page_list.append(prev) 40 for i in range(int(start_index),int(end_index)): 41 if i ==self.current_page: 42 temp = ‘<a class="page active" href="http://www.mamicode.com/%s?p=%s">%s</a>‘ %(base_url,i,i) 43 else: 44 temp = ‘<a class="page" href="http://www.mamicode.com/%s?p=%s">%s</a>‘ %(base_url,i,i) 45 page_list.append(temp) 46 if self.current_page == self.total_count: 47 nex = ‘<a class="page" href="javascript:void(0);">下一页</a>‘ 48 else: 49 nex = ‘<a class="page" href="http://www.mamicode.com/%s?p=%s">下一页</a>‘ %(base_url,self.current_page+1,) 50 page_list.append(nex) 51 jump = """ 52 <input type=‘text‘ /><a onclick=‘jumpTo(this, "%s?p=");‘>GO</a> 53 <script> 54 function jumpTo(ths,base){ 55 var val = ths.previousSibling.value; 56 location.href = http://www.mamicode.com/base + val;>57 } 58 </script> 59 """ %(base_url,) 60 page_list.append(jump) 61 page_str = mark_safe("".join(page_list)) 62 return page_str 63 64 pagination.py
views文件内容如下:
from django.shortcuts import render,HttpResponse from utils import pagination LIST=[] for i in range(109): LIST.append(i) def user_list(request): current_page = request.GET.get(‘p‘,1) current_page = int(current_page) page_obj = pagination.Page(current_page,len(LIST)) data = http://www.mamicode.com/LIST[page_obj.start:page_obj.end]"/userlist/") return render(request,‘userlist.html‘,{‘li‘:data,‘page_str‘:page_str})
templates文件下的userlist.html文件内容如下:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <style> 7 .pagination .page{ 8 display: inline-block; 9 padding: 5px; 10 background-color:darkmagenta; 11 margin: 5px; 12 } 13 .pagination .page.active{ 14 background-color: red; 15 color:white; 16 } 17 </style> 18 </head> 19 <body> 20 <ul> 21 {% for item in li %} 22 <li>{{ item }}</li> 23 {% endfor %} 24 </ul> 25 <div class="pagination"> 26 {{ page_str }} 27 </div> 28 </body> 29 </html> 30 31 userlist.html
运行程序,访问http://127.0.0.1:8000/user_list;
总结,分页时需要做三件事:
- 创建处理分页数据的类
- 根据分页数据获取数据
- 输出分页HTML,即:[上一页][1][2][3][4][5][下一页]
5. cookie
会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。
5.1 cookie机制
在程序中,会话跟踪是很重要的事情。理论上,一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话,二者不能混淆。例如,用户A在超市购买的任何商品都应该放在A的购物车内,不论是用户A什么时间购买的,这都是属于同一个会话的,不能放入用户B或用户C的购物车内,这不属于同一个会话。
而Web应用程序是使用HTTP协议传输数据的。HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。即用户A购买了一件商品放入购物车内,当再次购买商品时服务器已经无法判断该购买行为是属于用户A的会话还是用户B的会话了。要跟踪该会话,必须引入一种机制。
Cookie就是这样的一种机制。它可以弥补HTTP协议无状态的不足。在Session出现之前,基本上所有的网站都采用Cookie来跟踪会话。
5.2 什么是cookie?
Cookie意为“甜饼”,是由W3C组织提出,最早由Netscape社区发展的一种机制。目前Cookie已经成为标准,所有的主流浏览器如IE、Netscape、Firefox、Opera等都支持Cookie。
由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。
Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。
注意:Cookie功能需要浏览器的支持。
如果浏览器不支持Cookie(如大部分手机中的浏览器)或者把Cookie禁用了,Cookie功能就会失效。
5.3 获取cookie
request.COOKIES[‘key‘] request.get_signed_cookie(key, default=RAISE_ERROR, salt=‘‘, max_age=None) 参数: default: 默认值 salt: 加密盐 max_age: 后台控制过期时间
5.4 设置cookie
rep = HttpResponse(...) 或 rep = render(request, ...) rep.set_cookie(key,value,...) rep.set_signed_cookie(key,value,salt=‘加密盐‘,...) 参数: key, 键 value=http://www.mamicode.com/‘‘, 值>
由于cookie保存在客户端的电脑上,所以,JavaScript和jquery也可以操作cookie。
<script src=http://www.mamicode.com/‘/static/js/jquery.cookie.js‘></script>"list_pager_num", 30,{ path: ‘/‘ });
5.5 基于cookie实现用户登录
主程序urls文件:
from django.conf.urls import url,include from django.contrib import admin from app01 import views urlpatterns = [ url(r‘^login/‘, views.login), url(r‘^index/‘, views.index), ]
app目录下的views文件:
1 from django.shortcuts import render, HttpResponse,redirect 2 user_info = { 3 ‘cc‘: {‘pwd‘: "123123"}, 4 ‘root‘: {‘pwd‘: "111111"}, 5 } 6 def login(request): 7 if request.method == "GET": 8 return render(request,‘login.html‘) 9 if request.method == "POST": 10 u = request.POST.get(‘username‘) 11 p = request.POST.get(‘pwd‘) 12 dic = user_info.get(u) 13 if not dic: 14 return render(request,‘login.html‘) 15 if dic[‘pwd‘] == p: 16 res = redirect(‘/index/‘) 17 res.set_cookie(‘uname‘,u) 18 res.set_cookie(‘user_type‘,"asdfjalskdjf",httponly=True) 19 return res 20 else: 21 return render(request,‘login.html‘) 22 def index(reqeust): 23 # 获取当前已经登录的用户 24 v = reqeust.COOKIES.get(‘uname‘) 25 if not v: 26 return redirect(‘/login/‘) 27 return render(reqeust,‘index.html‘,{‘current_user‘: v})
app目录下的templates下新建login.html文件:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 <form action="/login/" method="POST"> 9 <input type="text" name="username" placeholder="用户名" /> 10 <input type="password" name="pwd" placeholder="密码" /> 11 <input type="submit" /> 12 </form> 13 </body> 14 </html> 15 16 login.html
新建index文件:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 <h1>欢迎登录:{{ current_user }}</h1> 9 </body> 10 </html> 11 12 index.html
运行程序并访问http://127.0.0.1:8000/login,输入用户名cc,密码123123,显示欢迎页面
5.6 基于cookie实现定制显示数据条数
pass
5.7 CBV和FBV用户认证装饰器
FBV:
views文件
def auth(func): def inner(reqeust,*args,**kwargs): v = reqeust.COOKIES.get(‘uname‘) if not v: return redirect(‘/login/‘) return func(reqeust, *args,**kwargs) return inner @auth def index(reqeust): # 获取当前已经登录的用户 v = reqeust.COOKIES.get(‘uname‘) return render(reqeust,‘index.html‘,{‘current_user‘: v})
CBV:
主程序urls文件:
from django.conf.urls import url,include from django.contrib import admin from app01 import views urlpatterns = [ url(r‘^login/‘, views.login), url(r‘^index/‘, views.index), url(r‘^order/‘, views.Order.as_view()), ]
app下的views文件:
from django.shortcuts import render, HttpResponse,redirect from django import views from django.utils.decorators import method_decorator @method_decorator(auth,name=‘dispatch‘) class Order(views.View): @method_decorator(auth) def dispatch(self, request, *args, **kwargs): return super(Order,self).dispatch(request, *args, **kwargs) @method_decorator(auth) def get(self,reqeust): v = reqeust.COOKIES.get(‘uname‘) return render(reqeust,‘index.html‘,{‘current_user‘: v}) @method_decorator(auth) def post(self,reqeust): v = reqeust.COOKIES.get(‘uname‘) return render(reqeust,‘index.html‘,{‘current_user‘: v})
web前端基础知识 - Django进阶