django基础五
视图
FBV: function based view 基于函数的视图
CBV: class based view 基于类的视图
CBV视图写法
#url.py from app01 import views url(r'^add_class/',views.add_class), #views.py 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')
CBV视图写法
#url.py from app01 import views url(r'^add_class/',views.AddClass.as_view()) #view.py from django.views import View #先导入django的View类 class AddClass(View): def get(self,request): #处理get请求 return render(request,'ass_class.html') def post(self,request): class_name = request.POST.get('class_name') models.Classes.create(name=class_name) return redirect('/class_list/')
as_view的执行流程
1.项目启动 加载url.py时,执行类.as_view() ——》 生成view函数, url(r'add_class/',views.AddClass.as_views())↓↓↓↓↓↓ url(r'add_class/',view) 每个url生成view函数都不一样 2.请求到来的时候执行view函数: '1.实例化类 ——》 在view函数中 self = cls(**initkwargs)实例化对象 self.request = request view函数return self.dispatch(request, *args, **kwargs) '2.执行self.dispatch(request, *args, **kwargs) 1.判断请求方式是否被允许: 1. 允许 通过反射获取到对应请求方式的方法 ——》 handler 2. 不允许 self.http_method_not_allowed ——》handler dispatch函数return handler(request, *args, **kwargs) 2.执行handler(request,*args,**kwargs) 返回响应 —— 》 浏览器
给视图加装饰器
#FBV #FBV本身就是一个函数,所以与普通函数加装饰器一样 import time def wrapper(func): def inner(*args,**kwargs): start = time.time() ret = func(*args,**kwargs) print(time.time()-start) return ret return inner @wrapper def st_add(request): return render(request,'st_add.html',{'k1':v1,'k2':v2}) #CBV加装饰器 import time from django.utils.decorators import method_decorator def wrapper(func): #装饰器函数 def inner(*args,**kwargs): start = time.time() ret = func(*args,**kwargs) print(time.time()-start) return ret return inner ---------------------------------------------------------------------- #方法一 class AddClaass(View): @method_decorator(wrapper) #相当于加有参数的装饰器 def get(self,request): return render(request,'add_class.html',{'k1':v1}) @method_decorator(wrapper) def post(self,request): class_name = request.POST.get('class_name') models.Classes.objects.create(name=class_name) return redirect('/class_list/') ---------------------------------------------------------------------- #方法二 #所有类绑定方法都要通过dispatch方法执行,那么直接给dispatch方法加装饰器,所有方法都有了 class AddClaass(View): @method_decorator(warppper) 给dispatch方法加装饰器,所有方法都加 def dispatch(self, request, *args, **kwargs): ret = super().dispatch(request, *args, **kwargs) #执行父类的dispatch方法完成任务 return ret def get(self,request): return render(request,'add_class.html',{'k1':v1}) def post(self,request): class_name = request.POST.get('class_name') models.Classes.objects.create(name=class_name) return redirect('/class_list/') ---------------------------------------------------------------------- #方法三 #所有类绑定方法都要通过dispatch方法执行,那么直接给dispatch方法加装饰器,所有方法都有了 class AddClaass(View): @method_decorator(warppper) #给dispatch方法加装饰器,所有方法都加这样更加省事 def dispatch(self, request, *args, **kwargs): start = time.time() #不加装饰器直接写 ret = super().dispatch(request, *args, **kwargs) #执行父类的dispatch方法完成任务 print('{}'.format(time.time()-start)) #不加装饰器直接写 return ret def get(self,request): return render(request,'add_class.html',{'k1':v1}) def post(self,request): class_name = request.POST.get('class_name') models.Classes.objects.create(name=class_name) return redirect('/class_list/') ---------------------------------------------------------------------- #方法四 @method_decorator(wrapper,name='post') #加在类上这样更加灵活 @method_decorator(wrapper,name='get') class AddClaass(View): def get(self,request): return render(request,'add_class.html',{'k1':v1}) def post(self,request): class_name = request.POST.get('class_name') models.Classes.objects.create(name=class_name) return redirect('/class_list/')
form表单上传文件
#上传文件的注意事项 1.form表单的属性 enctype="multipart/form_data" 2.input 的 type="file" 3.request.FILES.get('xx') #input框的name ----------------------------------------------------------------------- # html模板 <form action="" method="post" enctype="multipart/form_data"> {% csrf_token %} 上传文件: <input type="file" name="file"> <button>提交</button> </form> ----------------------------------------------------------------------- #视图 def upload(request): if request.mathod == "POST": file = request.FILES.get('file') path = r'D:\PY\progect\untitled\file\%s'%(file.name) with open(path,'wb')as f: for i in file.chunks(): f.write(i) print(f'{file.name}上传完成') return HttpResponse("上传完成") return render(request,'upload.html')
request对象的属性和方法
#request对象的属性 request.method # 请求方式 GET POST request.GET # url上携带的参数需要 .get()来取 request.POST # POST请求提交的数据(参数)需要 .get()来取 request.path_info # 请求路径信息(不包含IP和端口也不包含查询参数) /index/ request.body # 请求体的数据 get请求请求体为空 request.COOKIES # cookie request.session # session request.FILES # 上传的文件 request.META # 请求头的信息(一个大字典) ----------------------------------------------------------------------- #request对象的方法 request.get_full_path() # 完整的路径信息 只包含路径和参数不包含IP和端口 request.is_ajax() # 判断是否是ajax请求 request.get_host() # 获取主机的IP和端口
response对象
| 返回模式 | 返回内容 |
|---|---|
| HttpResponse('字符串') | 字符串 |
| render(request,'模板文件名',{'k1':v1}) | 完整的页面(把参数传进HTML文件替换后渲染) |
| redirect('要跳转的地址') | 重定向,返回响应头Location:url在重新发送个get请求 |
#redirect可以传递一个视图的名称 def my_view(request): ... return redirect('add_book',foo='bar') #redirect可以传递一个具体的网址 def my_view(request): ... return redirect('/add_book/') #redirect可以传递一个完整的网址 def my_view(request): ... return redirect('http://baidu.com/')
JsonResponse对象
JsonResponse是HttpResponse的子类,专门用来生成JSON编码的响应 #用法 from django.http import JsonResponse import json def json_data(request): data = {'name':'alex','age':73} return JsonResponse(data) #只能认识字典类型 #想要认识其他类型的可以这么写 # return JsonResponse(data,safe=False) #如果页面直接返回HttpResponse(data) 则只能取到 nameage 这样的字符串

浙公网安备 33010602011771号