Python学习第147天(Django之视图层)
views 视图层
小白必会三板斧
1.HttpResponse
2.render
3.redirect
django视图函数必须要返回一个HttpResponse对象
前后端分离
前端一个人干(前端转成自定义对象)
JSON.stringify() json.dumps()
JSON.parse() json.loads()
后端另一个干(python后端用字典)
只要涉及到数据交互,一般情况下都是用的json格式
后端只负责产生接口,前端调用该接口能拿到一个大字典
后端只需要写一个接口文档 里面描述字典的详细信息以及参数的传递
JsonReponse
import json from django.http import JsonResponse def reg(request): data = {'name':'haha哈哈', 'age':24} # 字典要想在前端展示出来,需要先序列化成字符串,才能基于网络二进制传输 res = json.dumps(data,ensure_ascii=False) # 传输的汉字不转码 return HttpResponse(res) # json方法 return JsonResponse(data,json_dumps_params={'ensure_ascii':False}) # JsonResponse 方法 lis = [1,2,3,4,5] print(request.path) print(request.get_full_path()) return JsonResponse(lis, safe=False) # 如果返回的不是字典 只需要修改safe参数为false即可
上传文件
form表单上传文件需要注意:
1.enctype需要由默认的urlencoded变成multipart/form-data 2.method需要由默认的get变成post 3.目前还需要考虑的是 提交post请求需要将配置文件中的csrf中间件注释 # 'django.middleware.csrf.CsrfViewMiddleware', 4.如果form表单上传文件,后端需要在request.FILES获取文件数据,而不再是POST里面
def file(request): if request.method == 'POST': # 文件不在post的字典中 file_obj = request.FILES.get('myfile') print(file_obj) # 文件对象 print(file_obj.name) # 文件名 # 操作文件 将文件写入后端 with open(file_obj.name, 'wb') as f: for line in file_obj.chunks(): # file_obj 是一个可迭代对象 f.write(line) return HttpResponse('收到') # 先将上传文件页面发到前端 return render(request,'file.html')
FBV与CBV
FBV(基于函数的视图) 面向函数式编程
CBV(基于类的视图) 面向对象式编程
views.py 文件中 from django.views import View class MyLogin(View): def get(self,request): print("from MyLogin get方法") return render(request,'login.html') def post(self,request): return HttpResponse("from MyLogin post方法") urls.py 文件中 url(r'^login/',views.MyLogin.as_view())
问题:
基于CBV的视图函数 get请求来就会走类里面get方法,post请求来就会走类里面post方法 为什么??
研究方向:
1.从url入手 url(r'^login/',views.MyLogin.as_view()) #由于函数名加括号执行优先级最高,所以这一句话一写完会立刻执行as_view()方法 @classonlymethod def as_view(cls, **initkwargs): # cls就是我们自己的写的类 MyLogin def view(request, *args, **kwargs): self = cls(**initkwargs) # 实例化产生MyLogin的对象 self = MyLogin(**ininkwargs) if hasattr(self, 'get') and not hasattr(self, 'head'): self.head = self.get self.request = request self.args = args self.kwargs = kwargs # 上面的几句话都仅仅是在给对象新增属性 return self.dispatch(request, *args, **kwargs) # dispatch返回什么 浏览器就会收到什么 # 对象在查找属性或者方法的时候 你一定要默念 先从对象自己这里找 然后从产生对象的类里面找 最后类的父类依次往后 return view 通过源码发现url匹配关系可以变形成 url(r'^login/',views.view) # FBV和CBV在路由匹配上是一致的 都是url后面跟函数的内存地址 2.当浏览器中输入login 会立刻触发view函数的运行 def dispatch(self, request, *args, **kwargs): # Try to dispatch to the right method; if a method doesn't exist, # defer to the error handler. Also defer to the error handler if the # request method isn't on the approved list. # 我们先以GET为例 if request.method.lower() in self.http_method_names: # 判断当前请求方法是否在默认的八个方法内 # 反射获取我们自己写的类产生的对象的属性或者方法 # 以GET为例 handler = getattr(self,'get','取不到报错的信息') # handler = get(request) handler = getattr(self,request.method.lower(),self.http_method_not_allowed) else: handler = self.http_method_not_allowed return handler(request, *args, **kwargs) # 直接调用我们自己的写类里面的get方法 # 源码中先通过判断请求方式是否符合默认的八个请求方法 然后通过反射获取到自定义类中的对应的方法执行