回顾前边的urls代码
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/', views.Cbv.as_view()), #CBV
]
再看下views中的代码
class Cbv(View):
def get(self,request):
return render(request,"index.html")
def post(self,request):
user = request.POST.get("user", False)
pwd = request.POST.get("pwd", False)
users_list = models.UserInfo.objects.all()
if not user or not pwd:
return render(request, "index.html", {"isnot":'yes'})
else:
user_obj = models.UserInfo.objects.filter(username=user,password=pwd)
if user_obj.first():
request.session['login'] = user_obj.first().username
return redirect("/page/")
else:
return render(request, "index.html", {"isexists": "false"})
可以看到在urls路由index路径时,会根据路由执行views里的Cbv类中的as_view方法,然而Cbv类中没有定义as_view方法,这时会找父类中的as_view方法。查看as_view方法,返回的是as_view方法里的view函数名(没有执行)。view函数返回的是执行的dispatch方法(views中CBV类中没有定义该方法则执行父类View中的)。dispatch方法是检查请求是否在('get‘’, ‘post’, ‘put’, ‘patch’, ‘delete’, ‘head’, ‘options’, ‘trace’)里面,没有会报错;如果请求的method在这些里面,则查看定义的CBV类中是否有对应的类方法(如get、post、put方法),没有会报错,有则会执行请求method的类方法。
现在使用CBV实现登录验证
views的部分代码
class Auth(View): #实现认证的类
def dispatch(self, request, *args, **kwargs): #定义一个dispatch方法
if request.session.get('login', False): #判断session是否存在即是否登录了
response = super(Auth, self).dispatch(request, *args, **kwargs) #执行父类View的dispatch方法
return response
else:
return redirect("/index") #没有登录跳转到index(index实现登录)
class Login(Auth): #定义登录后页面的类,继承自Auth类
def get(self, request): #urls路由会调用Auth类中的dispatch方法验证登录后执行get方法
obj_li = models.UserInfo.objects.all()
return render(request, 'login.html', locals())
urls部分代码
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/$', views.Login.as_view()), #请求login路径urls会路由到views中的Login类
url(r'^index/', views.Cbv.as_view()),
]