1、什么是视图?
一个视图函数(类),简称视图。是一个简单的python函数(类)。它接收Web请求,并返回Web响应。
说白了就是一个约定俗成写在Django项目App包下的views文件夹中的函数(类)。根据url匹配成功后,去执行这个视图函数(类),这个视图函数(类)中的代码段就是处理请求和响应的。
2、views中的新手必备三件套就出现了
from django.shortcuts import Httpresponse, render, redirect
这三者本质都是继承了Httpresponse。
当浏览器向服务器请求一个页面时,Django会创建一个Httpresponse对象,这个对象包含了所有的请求的元数据,然后作为参数传给视图函数执行,返回一个Httpresponse响应。
3、FBV和CBV
FBV(函数视图)
就是在views中写的函数
def add_student(request): if request.method == 'POST': student_name = request.POST.get('student_name') student_sex = request.POST.get('student_sex') student_Class = request.POST.get('student_Class') Student.objects.create(name=student_name, sex=student_sex, Student_id=student_Class) return redirect('/student_list/') new_Class = Class.objects.all() return render(request, 'add_student.html',{'Class_list':new_Class})
CBV(类视图)
首先:先在url中将函数名改成类名.as_view()
然后:在views中导入View from django.views import View
最后:创建类,继承View,在类中定义两个方法,分别为def get()方法 和 def post() 方法。
from django.views import View
Class Add_student(View): def get(self,request): new_Class = Class.objects.all() return render(request, 'add_student.html',{'Class_list':new_Class}) #get 请求对应的方法 def post(self,request): student_name = request.POST.get('student_name') student_sex = request.POST.get('student_sex') student_Class = request.POST.get('student_Class') Student.objects.create(name=student_name, sex=student_sex, Student_id=student_Class) return redirect('/student_list/') #post 请求对应的方法
4、使用装饰器装饰视图
1、使用装饰器装饰FBV
def wrapper(func): def inner(*args, **kwargs): start_time = time.time() ret = func(*args, **kwargs) end_time = time.time() print("used:", end_time-start_time) return ret return inner # FBV版添加班级 @wrapper # 相当于把add_class作为参数传给了wrapper()执行了add_class = wrapper(add_class) def add_class(request): if request.method == "POST": class_name = request.POST.get("class_name") models.Classes.objects.create(name=class_name) return redirect("/class_list/") return render(request, "add_class.html") # url匹配成功之后,会执行add_class函数,由于添加了装饰器,所以此时返回的inner函数进行了一个重新赋值,
赋值成为add_class,这样就不会改变原来的调用方式,实际上执行的是inner函数。
inner函数执行到func(*args,**kwargs)时,就相当于执行原函数add_class(),因为此时的func就是add_class作为实参传给wrapper的。
原函数的返回值需要在inner函数中用变量ret接收,然后返回ret.
2、使用装饰器装饰CBV
由于类中的方法和函数不同,所以不能直接将函数的装饰器给类中的方法是用,需要先将其撞环卫方法装饰器。
在django中提供了method_decorator,用于将装饰器转换为方法装饰器。
from django.views import View from django.utils.decorators import method_decorator #导入方法装饰器 def wrapper(func): def inner(*args, **kwargs): start_time = time.time() ret = func(*args, **kwargs) end_time = time.time() print("used:", end_time-start_time) return ret return inner class AddClass(View): @method_decorator(wrapper) # 将wrapper作为方法装饰器给get方法装一个装饰器 def get(self, request): return render(request, "add_class.html") def post(self, request): class_name = request.POST.get("class_name") models.Classes.objects.create(name=class_name) return redirect("/class_list/")
如果需要给类中的所有方法都装装饰器,就可以自己手动写一个dispatch()方法,在这个方法上装个装饰器。
因为使用BCV时,请求过来后先执行的是dispatch()这个方法,所以给dispatch方法上加装饰器,就不需要给其他请求方法加装饰器了
from django.views import View from django.utils.decorators import method_decorator def wrapper(func): def inner(*args, **kwargs): start_time = time.time() ret = func(*args, **kwargs) end_time = time.time() print("used:", end_time-start_time) return ret return inner class Login(View): @method_decorator(wrapper) #给dispatch介个装饰器,就相当于给类中所有的请求方法都加了装饰器。 def dispatch(self, request, *args, **kwargs): print('before') obj = super(Login,self).dispatch(request, *args, **kwargs) print('after') return obj def get(self,request): return render(request,'login.html') def post(self,request): print(request.POST.get('user')) return HttpResponse('Login.post')
5、request对象和response对象
1、request
request.method POST GET PUT DELETE OPTION
request.GET 或取到的是url ?之后的内容 ?id=11&name=sss {} 是一个字典对象
request.POST 获取到的是提交POST请求时的类字典对象
request.body 获取到的是一个bytes类型你给的内容,里边包含了HTTP格式请求中的数据
request.FILES enctype = 'mutlipart/form-data'
request.path_info 获取到的是不包括域名+端口号和?后边内容的一个路径
request.get_host() 获取到的是域名加端口号
request.get_full_path() 不包括域名和端口号的路径,但是包括参数
2、response
HttpResponse('OK') 给页面返回一个内容,Content-Type:text/html;charset = utf-8
render(request,'html文件名',{ 要渲染替换的内容}) 返回的是一个完整的页面
redirect('/press_list/') 页面跳转,重定向,实质是加一个响应头 Location :/press_list/
JsonResponse({ }) 用JsonResponse响应的话,Django会通过Content-Type:application/json 变成Json格式的内容,如果HttpResponse想要变成json格式,只需要将Content-Type:text/html;charset = utf-8改成Content-Type:application/json