FBV & CBV
FBV & CBV
-
FBV 基于函数的view视图写法--> function based view
-
CBV 基于类的view视图写法 --> class based view
# urls.py # CBV url(r'^loginview/', views.LoginView.as_view()) # views.py # ################################# CBV(类式视图) ############################################ from django.views import View # 导入views包下的View类 class LoginView(View): # 继承View类 # GET def get(self, request): # 类中get方法对应GET请求 return render(request, 'loginview.html') # POST def post(self, request): username = request.POST.get('username') password = request.POST.get('password') if username == 'sunny' and password == '123': return redirect('/home/') else: return HttpResponse('用户名不存在或者密码错误!')
-
View类dispatch扩展
from django.shortcuts import render, HttpResponse, redirect # Create your views here. # ################################# FBV(函数式视图) ############################################ def index(request): # http相关请求信息--封装--HttpRequest对象-传参-->request # request 方法 if request.method == 'GET': print('---------------------GET---------------------') print('GET:', request.GET) # get请求提交的数据 print('META:', request.META) # 所有的HTTP请求首部相关信息, 具体的头部信息取决于客户端和服务端 print('path:', request.path) # /index/ print('path_info:', request.path_info) # /index/返回用户访问的url,不包含域名 print('full_path:', request.get_full_path()) # /index/?username=Sunny&password=123 print('body:', request.body) return render(request, 'index.html') else: # index.html中,表单form action="", action为空表示从当前路径下提交数据, method="get",method,请求方式:get or post print('---------------------POST---------------------') print('method:', request.method) # 请求方法:get还是post print('body:', request.body) # 请求体, byte类型, request.POST数据就是从body中取到的.b'username=sunny&password=1234'(socket发送的byte类型对象) print('path:', request.path) print('path_info:', request.path_info) # 返回用户访问的url,不包含域名 print('full_path:', request.get_full_path()) print('META:', request.META) # 所有的HTTP请求首部相关信息, 具体的头部信息取决于客户端和服务端 print('POST:', request.POST) # 包含所有HTTP POST参数(request.body中的数据封装)的类字典对象,<QueryDict: {'username': ['sunny'], 'password': ['1234']}> return HttpResponse('Post 请求已响应') # ################ HTTP协议是基于请求响应的协议,一请求对应一响应 ################ # HTTP协议 -- 应用层协议,下层传输层 -- TCP协议(一收一发),基于流,稳定 # django和浏览器都封装了socket # views视图处理的是对于浏览器请求的响应 # 1.浏览器get请求:/login/ # 服务器响应: login.html # 2.浏览器post请求: {'username':'sunny', 'password':'1234'} # 服务器响应: status code:302 not found(重定向状态码), location: /home/ # 3.浏览器get请求: /home/ # 服务器响应:home.html def login(request): if request.method == 'GET': return render(request, 'login.html') # 响应html页面 else: username = request.POST.get('username') password = request.POST.get('password') if username == 'sunny' and password == '1234': return redirect('/home/') # 重定向页面, 参数为路径,需要在urls中定义 # return render(request, 'home.html') else: return HttpResponse('Wrong user name or password!Please Retry!') # 响应消息 # 首页 def home(request): return render(request, 'home.html') # ################################# CBV(类式视图) ############################################ from django.views import View # 导入views包下的View类 class LoginView(View): # 继承View类,view中的dispatch方法是反射,调用LoginView实例对象中的反射方法 # dispatch方法作用: 分发请求方法到对应的视图方法(通过反射类中的视图方法) def dispatch(self, request, *args, **kwargs): # 重写父类方法,扩展, 有请求都先走这个类方法, 然后通过类方法中的反射调用LoginView中的方法 print(request.method, 'before') # 请求前,请求后,都可以做些其他事 print('user agent:', request.META.get('HTTP_USER_AGENT')) # 例如先通过request.META可以判断请求对象是不是浏览器或者其他,做些其他事 ret = super().dispatch(request, *args, **kwargs) # python3: super()自动把默认的View,self参数传入父类, 等价于super(View, self) # 对象调用方法时候,会自动把自身当作参数传入 # super().dispatch(request, *args, **kwargs) 等价于super().dispatch(super(),request, *args, **kwargs) print(request.method, 'after') return ret # 父类方法返回了值,所以子类重写的方法也必须返回值供父类View方法继续调用 # GET def get(self, request): return render(request, 'loginview.html') # POST def post(self, request): username = request.POST.get('username') password = request.POST.get('password') if username == 'sunny' and password == '123': return redirect('/home/') else: return HttpResponse('用户名不存在或者密码错误!')
-